summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorZach Copley <zach@status.net>2010-02-26 21:34:39 +0000
committerZach Copley <zach@status.net>2010-02-26 21:34:39 +0000
commit1883da64185022866572f9eb27938b4cc7724328 (patch)
treea21f97c220b8b4da4435756979a2c5ec74c58773 /lib
parentd4b47eb6995942f1a906eb3cd5c6bd8c98c3b2cf (diff)
parentc82cee18769763d105304f09de9b6b4079e48aae (diff)
Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing
Diffstat (limited to 'lib')
-rw-r--r--lib/action.php2
-rw-r--r--lib/activity.php380
-rw-r--r--lib/adminpanelaction.php29
-rw-r--r--lib/apiaction.php (renamed from lib/api.php)21
-rw-r--r--lib/apiauth.php1
-rw-r--r--lib/atomnoticefeed.php5
-rw-r--r--lib/common.php2
-rw-r--r--lib/default.php1
-rw-r--r--lib/distribqueuehandler.php12
-rw-r--r--lib/joinform.php2
-rw-r--r--lib/leaveform.php2
-rw-r--r--lib/noticelist.php23
-rw-r--r--lib/profilequeuehandler.php52
-rw-r--r--lib/queuemanager.php3
-rw-r--r--lib/router.php7
-rw-r--r--lib/util.php22
16 files changed, 465 insertions, 99 deletions
diff --git a/lib/action.php b/lib/action.php
index fa9ddb911..a7e0eb33b 100644
--- a/lib/action.php
+++ b/lib/action.php
@@ -976,7 +976,7 @@ class Action extends HTMLOutputter // lawsuit
if (is_null($arg)) {
return $def;
- } else if (in_array($arg, array('true', 'yes', '1'))) {
+ } else if (in_array($arg, array('true', 'yes', '1', 'on'))) {
return true;
} else if (in_array($arg, array('false', 'no', '0'))) {
return false;
diff --git a/lib/activity.php b/lib/activity.php
index 5cbab8d5f..b20153213 100644
--- a/lib/activity.php
+++ b/lib/activity.php
@@ -154,7 +154,15 @@ class PoCo
PoCo::NS
);
- array_push($urls, new PoCoURL($type, $value, $primary));
+ $isPrimary = false;
+
+ if (isset($primary) && $primary == 'true') {
+ $isPrimary = true;
+ }
+
+ // @todo check to make sure a primary hasn't already been added
+
+ array_push($urls, new PoCoURL($type, $value, $isPrimary));
}
return $urls;
}
@@ -167,16 +175,18 @@ class PoCo
PoCo::NS
);
- $formatted = ActivityUtils::childContent(
- $addressEl,
- PoCoAddress::FORMATTED,
- self::NS
- );
+ if (!empty($addressEl)) {
+ $formatted = ActivityUtils::childContent(
+ $addressEl,
+ PoCoAddress::FORMATTED,
+ self::NS
+ );
- if (!empty($formatted)) {
- $address = new PoCoAddress();
- $address->formatted = $formatted;
- return $address;
+ if (!empty($formatted)) {
+ $address = new PoCoAddress();
+ $address->formatted = $formatted;
+ return $address;
+ }
}
return null;
@@ -213,6 +223,46 @@ class PoCo
return $poco;
}
+ function fromGroup($group)
+ {
+ if (empty($group)) {
+ return null;
+ }
+
+ $poco = new PoCo();
+
+ $poco->preferredUsername = $group->nickname;
+ $poco->displayName = $group->getBestName();
+
+ $poco->note = $group->description;
+
+ $paddy = new PoCoAddress();
+ $paddy->formatted = $group->location;
+ $poco->address = $paddy;
+
+ if (!empty($group->homepage)) {
+ array_push(
+ $poco->urls,
+ new PoCoURL(
+ 'homepage',
+ $group->homepage,
+ true
+ )
+ );
+ }
+
+ return $poco;
+ }
+
+ function getPrimaryURL()
+ {
+ foreach ($this->urls as $url) {
+ if ($url->primary) {
+ return $url;
+ }
+ }
+ }
+
function asString()
{
$xs = new XMLStringer(true);
@@ -292,7 +342,7 @@ class ActivityUtils
* @return string related link, if any
*/
- static function getLink($element, $rel, $type=null)
+ static function getLink(DOMNode $element, $rel, $type=null)
{
$links = $element->getElementsByTagnameNS(self::ATOM, self::LINK);
@@ -310,6 +360,25 @@ class ActivityUtils
return null;
}
+ static function getLinks(DOMNode $element, $rel, $type=null)
+ {
+ $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK);
+ $out = array();
+
+ foreach ($links as $link) {
+
+ $linkRel = $link->getAttribute(self::REL);
+ $linkType = $link->getAttribute(self::TYPE);
+
+ if ($linkRel == $rel &&
+ (is_null($type) || $linkType == $type)) {
+ $out[] = $link;
+ }
+ }
+
+ return $out;
+ }
+
/**
* Gets the first child element with the given tag
*
@@ -320,7 +389,7 @@ class ActivityUtils
* @return DOMElement found element or null
*/
- static function child($element, $tag, $namespace=self::ATOM)
+ static function child(DOMNode $element, $tag, $namespace=self::ATOM)
{
$els = $element->childNodes;
if (empty($els) || $els->length == 0) {
@@ -345,7 +414,7 @@ class ActivityUtils
* @return string content of the child
*/
- static function childContent($element, $tag, $namespace=self::ATOM)
+ static function childContent(DOMNode $element, $tag, $namespace=self::ATOM)
{
$el = self::child($element, $tag, $namespace);
@@ -415,6 +484,75 @@ class ActivityUtils
}
}
+// XXX: Arg! This wouldn't be necessary if we used Avatars conistently
+class AvatarLink
+{
+ public $url;
+ public $type;
+ public $size;
+ public $width;
+ public $height;
+
+ function __construct($element=null)
+ {
+ if ($element) {
+ // @fixme use correct namespaces
+ $this->url = $element->getAttribute('href');
+ $this->type = $element->getAttribute('type');
+ $width = $element->getAttribute('media:width');
+ if ($width != null) {
+ $this->width = intval($width);
+ }
+ $height = $element->getAttribute('media:height');
+ if ($height != null) {
+ $this->height = intval($height);
+ }
+ }
+ }
+
+ static function fromAvatar($avatar)
+ {
+ if (empty($avatar)) {
+ return null;
+ }
+ $alink = new AvatarLink();
+ $alink->type = $avatar->mediatype;
+ $alink->height = $avatar->height;
+ $alink->width = $avatar->width;
+ $alink->url = $avatar->displayUrl();
+ return $alink;
+ }
+
+ static function fromFilename($filename, $size)
+ {
+ $alink = new AvatarLink();
+ $alink->url = $filename;
+ $alink->height = $size;
+ if (!empty($filename)) {
+ $alink->width = $size;
+ $alink->type = self::mediatype($filename);
+ } else {
+ $alink->url = User_group::defaultLogo($size);
+ $alink->type = 'image/png';
+ }
+ return $alink;
+ }
+
+ // yuck!
+ static function mediatype($filename) {
+ $ext = strtolower(end(explode('.', $filename)));
+ if ($ext == 'jpeg') {
+ $ext = 'jpg';
+ }
+ // hope we don't support any others
+ $types = array('png', 'gif', 'jpg', 'jpeg');
+ if (in_array($ext, $types)) {
+ return 'image/' . $ext;
+ }
+ return null;
+ }
+}
+
/**
* A noun-ish thing in the activity universe
*
@@ -471,7 +609,7 @@ class ActivityObject
public $content;
public $link;
public $source;
- public $avatar;
+ public $avatarLinks = array();
public $geopoint;
public $poco;
public $displayName;
@@ -494,6 +632,12 @@ class ActivityObject
$this->element = $element;
+ $this->geopoint = $this->_childContent(
+ $element,
+ ActivityContext::POINT,
+ ActivityContext::GEORSS
+ );
+
if ($element->tagName == 'author') {
$this->type = self::PERSON; // XXX: is this fair?
@@ -533,8 +677,10 @@ class ActivityObject
if ($this->type == self::PERSON || $this->type == self::GROUP) {
$this->displayName = $this->title;
- // @fixme we may have multiple avatars with different resolutions specified
- $this->avatar = ActivityUtils::getLink($element, 'avatar');
+ $avatars = ActivityUtils::getLinks($element, 'avatar');
+ foreach ($avatars as $link) {
+ $this->avatarLinks[] = new AvatarLink($link);
+ }
$this->poco = new PoCo($element);
}
@@ -585,10 +731,40 @@ class ActivityObject
$object->id = $profile->getUri();
$object->title = $profile->getBestName();
$object->link = $profile->profileurl;
- $object->avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+
+ $orig = $profile->getOriginalAvatar();
+
+ if (!empty($orig)) {
+ $object->avatarLinks[] = AvatarLink::fromAvatar($orig);
+ }
+
+ $sizes = array(
+ AVATAR_PROFILE_SIZE,
+ AVATAR_STREAM_SIZE,
+ AVATAR_MINI_SIZE
+ );
+
+ foreach ($sizes as $size) {
+
+ $alink = null;
+ $avatar = $profile->getAvatar($size);
+
+ if (!empty($avatar)) {
+ $alink = AvatarLink::fromAvatar($avatar);
+ } else {
+ $alink = new AvatarLink();
+ $alink->type = 'image/png';
+ $alink->height = $size;
+ $alink->width = $size;
+ $alink->url = Avatar::defaultImage($size);
+ }
+
+ $object->avatarLinks[] = $alink;
+ }
if (isset($profile->lat) && isset($profile->lon)) {
- $object->geopoint = (float)$profile->lat . ' ' . (float)$profile->lon;
+ $object->geopoint = (float)$profile->lat
+ . ' ' . (float)$profile->lon;
}
$object->poco = PoCo::fromProfile($profile);
@@ -596,6 +772,36 @@ class ActivityObject
return $object;
}
+ static function fromGroup($group)
+ {
+ $object = new ActivityObject();
+
+ $object->type = ActivityObject::GROUP;
+ $object->id = $group->getUri();
+ $object->title = $group->getBestName();
+ $object->link = $group->getUri();
+
+ $object->avatarLinks[] = AvatarLink::fromFilename(
+ $group->homepage_logo,
+ AVATAR_PROFILE_SIZE
+ );
+
+ $object->avatarLinks[] = AvatarLink::fromFilename(
+ $group->stream_logo,
+ AVATAR_STREAM_SIZE
+ );
+
+ $object->avatarLinks[] = AvatarLink::fromFilename(
+ $group->mini_logo,
+ AVATAR_MINI_SIZE
+ );
+
+ $object->poco = PoCo::fromGroup($group);
+
+ return $object;
+ }
+
+
function asString($tag='activity:object')
{
$xs = new XMLStringer(true);
@@ -633,16 +839,19 @@ class ActivityObject
if ($this->type == ActivityObject::PERSON
|| $this->type == ActivityObject::GROUP) {
- $xs->element(
- 'link', array(
- 'type' => empty($this->avatar) ? 'image/png' : $this->avatar->mediatype,
- 'rel' => 'avatar',
- 'href' => empty($this->avatar)
- ? Avatar::defaultImage(AVATAR_PROFILE_SIZE)
- : $this->avatar->displayUrl()
- ),
- null
- );
+
+ foreach ($this->avatarLinks as $avatar) {
+ $xs->element(
+ 'link', array(
+ 'rel' => 'avatar',
+ 'type' => $avatar->type,
+ 'media:width' => $avatar->width,
+ 'media:height' => $avatar->height,
+ 'href' => $avatar->url
+ ),
+ null
+ );
+ }
}
if (!empty($this->geopoint)) {
@@ -691,6 +900,9 @@ class ActivityVerb
const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite';
const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow';
const LEAVE = 'http://ostatus.org/schema/1.0/leave';
+
+ // For simple profile-update pings; no content to share.
+ const UPDATE_PROFILE = 'http://ostatus.org/schema/1.0/update-profile';
}
class ActivityContext
@@ -756,22 +968,29 @@ class ActivityContext
for ($i = 0; $i < $points->length; $i++) {
$point = $points->item($i)->textContent;
- $point = str_replace(',', ' ', $point); // per spec "treat commas as whitespace"
- $point = preg_replace('/\s+/', ' ', $point);
- $point = trim($point);
- $coords = explode(' ', $point);
- if (count($coords) == 2) {
- list($lat, $lon) = $coords;
- if (is_numeric($lat) && is_numeric($lon)) {
- common_log(LOG_INFO, "Looking up location for $lat $lon from georss");
- return Location::fromLatLon($lat, $lon);
- }
- }
- common_log(LOG_ERR, "Ignoring bogus georss:point value $point");
+ return self::locationFromPoint($point);
}
return null;
}
+
+ // XXX: Move to ActivityUtils or Location?
+ static function locationFromPoint($point)
+ {
+ $point = str_replace(',', ' ', $point); // per spec "treat commas as whitespace"
+ $point = preg_replace('/\s+/', ' ', $point);
+ $point = trim($point);
+ $coords = explode(' ', $point);
+ if (count($coords) == 2) {
+ list($lat, $lon) = $coords;
+ if (is_numeric($lat) && is_numeric($lon)) {
+ common_log(LOG_INFO, "Looking up location for $lat $lon from georss point");
+ return Location::fromLatLon($lat, $lon);
+ }
+ }
+ common_log(LOG_ERR, "Ignoring bogus georss:point value $point");
+ return null;
+ }
}
/**
@@ -824,6 +1043,7 @@ class Activity
public $content; // HTML content of activity
public $id; // ID of the activity
public $title; // title of the activity
+ public $categories = array(); // list of AtomCategory objects
/**
* Turns a regular old Atom <entry> into a magical activity
@@ -912,6 +1132,14 @@ class Activity
$this->summary = ActivityUtils::childContent($entry, 'summary');
$this->id = ActivityUtils::childContent($entry, 'id');
$this->content = ActivityUtils::getContent($entry);
+
+ $catEls = $entry->getElementsByTagNameNS(self::ATOM, 'category');
+ if ($catEls) {
+ for ($i = 0; $i < $catEls->length; $i++) {
+ $catEl = $catEls->item($i);
+ $this->categories[] = new AtomCategory($catEl);
+ }
+ }
}
/**
@@ -934,7 +1162,8 @@ class Activity
'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/',
'xmlns:georss' => 'http://www.georss.org/georss',
'xmlns:ostatus' => 'http://ostatus.org/schema/1.0',
- 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0');
+ 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0',
+ 'xmlns:media' => 'http://purl.org/syndication/atommedia');
} else {
$attrs = array();
}
@@ -957,11 +1186,28 @@ class Activity
}
// XXX: add context
- // XXX: add target
+ $xs->elementStart('author');
+ $xs->element('uri', array(), $this->actor->id);
+ if ($this->actor->title) {
+ $xs->element('name', array(), $this->actor->title);
+ }
+ $xs->elementEnd('author');
$xs->raw($this->actor->asString('activity:actor'));
+
$xs->element('activity:verb', null, $this->verb);
- $xs->raw($this->object->asString());
+
+ if ($this->object) {
+ $xs->raw($this->object->asString());
+ }
+
+ if ($this->target) {
+ $xs->raw($this->target->asString('activity:target'));
+ }
+
+ foreach ($this->categories as $cat) {
+ $xs->raw($cat->asString());
+ }
$xs->elementEnd('entry');
@@ -972,4 +1218,50 @@ class Activity
{
return ActivityUtils::child($element, $tag, $namespace);
}
-} \ No newline at end of file
+}
+
+class AtomCategory
+{
+ public $term;
+ public $scheme;
+ public $label;
+
+ function __construct($element=null)
+ {
+ if ($element && $element->attributes) {
+ $this->term = $this->extract($element, 'term');
+ $this->scheme = $this->extract($element, 'scheme');
+ $this->label = $this->extract($element, 'label');
+ }
+ }
+
+ protected function extract($element, $attrib)
+ {
+ $node = $element->attributes->getNamedItemNS(Activity::ATOM, $attrib);
+ if ($node) {
+ return trim($node->textContent);
+ }
+ $node = $element->attributes->getNamedItem($attrib);
+ if ($node) {
+ return trim($node->textContent);
+ }
+ return null;
+ }
+
+ function asString()
+ {
+ $attribs = array();
+ if ($this->term !== null) {
+ $attribs['term'] = $this->term;
+ }
+ if ($this->scheme !== null) {
+ $attribs['scheme'] = $this->scheme;
+ }
+ if ($this->label !== null) {
+ $attribs['label'] = $this->label;
+ }
+ $xs = new XMLStringer();
+ $xs->element('category', $attribs);
+ return $xs->asString();
+ }
+}
diff --git a/lib/adminpanelaction.php b/lib/adminpanelaction.php
index f05627b31..536d97cdf 100644
--- a/lib/adminpanelaction.php
+++ b/lib/adminpanelaction.php
@@ -103,7 +103,7 @@ class AdminPanelAction extends Action
$name = mb_substr($name, 0, -10);
- if (!in_array($name, common_config('admin', 'panels'))) {
+ if (!self::canAdmin($name)) {
$this->clientError(_('Changes to that panel are not allowed.'), 403);
return false;
}
@@ -262,6 +262,17 @@ class AdminPanelAction extends Action
return $result;
}
+
+ function canAdmin($name)
+ {
+ $isOK = false;
+
+ if (Event::handle('AdminPanelCheck', array($name, &$isOK))) {
+ $isOK = in_array($name, common_config('admin', 'panels'));
+ }
+
+ return $isOK;
+ }
}
/**
@@ -307,32 +318,32 @@ class AdminPanelNav extends Widget
if (Event::handle('StartAdminPanelNav', array($this))) {
- if ($this->canAdmin('site')) {
+ if (AdminPanelAction::canAdmin('site')) {
$this->out->menuItem(common_local_url('siteadminpanel'), _('Site'),
_('Basic site configuration'), $action_name == 'siteadminpanel', 'nav_site_admin_panel');
}
- if ($this->canAdmin('design')) {
+ if (AdminPanelAction::canAdmin('design')) {
$this->out->menuItem(common_local_url('designadminpanel'), _('Design'),
_('Design configuration'), $action_name == 'designadminpanel', 'nav_design_admin_panel');
}
- if ($this->canAdmin('user')) {
+ if (AdminPanelAction::canAdmin('user')) {
$this->out->menuItem(common_local_url('useradminpanel'), _('User'),
_('User configuration'), $action_name == 'useradminpanel', 'nav_design_admin_panel');
}
- if ($this->canAdmin('access')) {
+ if (AdminPanelAction::canAdmin('access')) {
$this->out->menuItem(common_local_url('accessadminpanel'), _('Access'),
_('Access configuration'), $action_name == 'accessadminpanel', 'nav_design_admin_panel');
}
- if ($this->canAdmin('paths')) {
+ if (AdminPanelAction::canAdmin('paths')) {
$this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'),
_('Paths configuration'), $action_name == 'pathsadminpanel', 'nav_design_admin_panel');
}
- if ($this->canAdmin('sessions')) {
+ if (AdminPanelAction::canAdmin('sessions')) {
$this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'),
_('Sessions configuration'), $action_name == 'sessionsadminpanel', 'nav_design_admin_panel');
}
@@ -342,8 +353,4 @@ class AdminPanelNav extends Widget
$this->action->elementEnd('ul');
}
- function canAdmin($name)
- {
- return in_array($name, common_config('admin', 'panels'));
- }
}
diff --git a/lib/api.php b/lib/apiaction.php
index 0bcf4cc21..2af150ab9 100644
--- a/lib/api.php
+++ b/lib/apiaction.php
@@ -1218,7 +1218,12 @@ class ApiAction extends Action
return User_group::staticGet($this->arg('id'));
} else if ($this->arg('id')) {
$nickname = common_canonical_nickname($this->arg('id'));
- return User_group::staticGet('nickname', $nickname);
+ $local = Local_group::staticGet('nickname', $nickname);
+ if (empty($local)) {
+ return null;
+ } else {
+ return User_group::staticGet('id', $local->id);
+ }
} else if ($this->arg('group_id')) {
// This is to ensure that a non-numeric user_id still
// overrides screen_name even if it doesn't get used
@@ -1227,14 +1232,24 @@ class ApiAction extends Action
}
} else if ($this->arg('group_name')) {
$nickname = common_canonical_nickname($this->arg('group_name'));
- return User_group::staticGet('nickname', $nickname);
+ $local = Local_group::staticGet('nickname', $nickname);
+ if (empty($local)) {
+ return null;
+ } else {
+ return User_group::staticGet('id', $local->id);
+ }
}
} else if (is_numeric($id)) {
return User_group::staticGet($id);
} else {
$nickname = common_canonical_nickname($id);
- return User_group::staticGet('nickname', $nickname);
+ $local = Local_group::staticGet('nickname', $nickname);
+ if (empty($local)) {
+ return null;
+ } else {
+ return User_group::staticGet('id', $local->group_id);
+ }
}
}
diff --git a/lib/apiauth.php b/lib/apiauth.php
index 25e2196cf..5090871cf 100644
--- a/lib/apiauth.php
+++ b/lib/apiauth.php
@@ -38,7 +38,6 @@ if (!defined('STATUSNET')) {
exit(1);
}
-require_once INSTALLDIR . '/lib/api.php';
require_once INSTALLDIR . '/lib/apioauth.php';
/**
diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php
index d2bf2a416..3c3556cb9 100644
--- a/lib/atomnoticefeed.php
+++ b/lib/atomnoticefeed.php
@@ -65,6 +65,11 @@ class AtomNoticeFeed extends Atom10Feed
);
$this->addNamespace(
+ 'media',
+ 'http://purl.org/syndication/atommedia'
+ );
+
+ $this->addNamespace(
'poco',
'http://portablecontacts.net/spec/1.0'
);
diff --git a/lib/common.php b/lib/common.php
index 68723955e..2dbe3b3c5 100644
--- a/lib/common.php
+++ b/lib/common.php
@@ -22,7 +22,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
//exit with 200 response, if this is checking fancy from the installer
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
-define('STATUSNET_VERSION', '0.9.0beta5');
+define('STATUSNET_VERSION', '0.9.0beta6');
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
define('STATUSNET_CODENAME', 'Stand');
diff --git a/lib/default.php b/lib/default.php
index bb7708bfc..d849055c2 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -278,7 +278,6 @@ $default =
'TightUrl' => array('shortenerName' => '2tu.us', 'freeService' => true,'serviceUrl'=>'http://2tu.us/?save=y&url=%1$s'),
'Geonames' => null,
'Mapstraction' => null,
- 'Linkback' => null,
'WikiHashtags' => null,
'OpenID' => null),
),
diff --git a/lib/distribqueuehandler.php b/lib/distribqueuehandler.php
index dc183fb36..d2be7a92c 100644
--- a/lib/distribqueuehandler.php
+++ b/lib/distribqueuehandler.php
@@ -63,24 +63,12 @@ class DistribQueueHandler
// XXX: do we need to change this for remote users?
try {
- $notice->saveTags();
- } catch (Exception $e) {
- $this->logit($notice, $e);
- }
-
- try {
$notice->addToInboxes();
} catch (Exception $e) {
$this->logit($notice, $e);
}
try {
- $notice->saveUrls();
- } catch (Exception $e) {
- $this->logit($notice, $e);
- }
-
- try {
Event::handle('EndNoticeSave', array($notice));
// Enqueue for other handlers
} catch (Exception $e) {
diff --git a/lib/joinform.php b/lib/joinform.php
index aefb553aa..aa8bc20e2 100644
--- a/lib/joinform.php
+++ b/lib/joinform.php
@@ -100,7 +100,7 @@ class JoinForm extends Form
function action()
{
return common_local_url('joingroup',
- array('nickname' => $this->group->nickname));
+ array('id' => $this->group->id));
}
/**
diff --git a/lib/leaveform.php b/lib/leaveform.php
index e63d96ee8..5469b5704 100644
--- a/lib/leaveform.php
+++ b/lib/leaveform.php
@@ -100,7 +100,7 @@ class LeaveForm extends Form
function action()
{
return common_local_url('leavegroup',
- array('nickname' => $this->group->nickname));
+ array('id' => $this->group->id));
}
/**
diff --git a/lib/noticelist.php b/lib/noticelist.php
index dcf17be08..7d1d2828f 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -380,12 +380,12 @@ class NoticeListItem extends Widget
function showNoticeLink()
{
- if($this->notice->is_local == Notice::LOCAL_PUBLIC || $this->notice->is_local == Notice::LOCAL_NONPUBLIC){
- $noticeurl = common_local_url('shownotice',
- array('notice' => $this->notice->id));
- }else{
- $noticeurl = $this->notice->uri;
- }
+ $noticeurl = $this->notice->bestUrl();
+
+ // above should always return an URL
+
+ assert(!empty($noticeurl));
+
$this->out->elementStart('a', array('rel' => 'bookmark',
'class' => 'timestamp',
'href' => $noticeurl));
@@ -540,16 +540,13 @@ class NoticeListItem extends Widget
function showContext()
{
$hasConversation = false;
- if( !empty($this->notice->conversation)
- && $this->notice->conversation != $this->notice->id){
- $hasConversation = true;
- }else{
- $conversation = Notice::conversationStream($this->notice->id, 1, 1);
- if($conversation->N > 0){
+ if (!empty($this->notice->conversation)) {
+ $conversation = Notice::conversationStream($this->notice->conversation, 1, 1);
+ if ($conversation->N > 0) {
$hasConversation = true;
}
}
- if ($hasConversation){
+ if ($hasConversation) {
$this->out->text(' ');
$convurl = common_local_url('conversation',
array('id' => $this->notice->conversation));
diff --git a/lib/profilequeuehandler.php b/lib/profilequeuehandler.php
new file mode 100644
index 000000000..6ce93229b
--- /dev/null
+++ b/lib/profilequeuehandler.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, 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/>.
+ */
+
+/**
+ * @package QueueHandler
+ * @maintainer Brion Vibber <brion@status.net>
+ */
+
+class ProfileQueueHandler extends QueueHandler
+{
+
+ function transport()
+ {
+ return 'profile';
+ }
+
+ function handle($profile)
+ {
+ if (!($profile instanceof Profile)) {
+ common_log(LOG_ERR, "Got a bogus profile, not broadcasting");
+ return true;
+ }
+
+ if (Event::handle('StartBroadcastProfile', array($profile))) {
+ require_once(INSTALLDIR.'/lib/omb.php');
+ try {
+ omb_broadcast_profile($profile);
+ } catch (Exception $e) {
+ common_log(LOG_ERR, "Failed sending OMB profiles: " . $e->getMessage());
+ }
+ }
+ Event::handle('EndBroadcastProfile', array($profile));
+ return true;
+ }
+
+}
diff --git a/lib/queuemanager.php b/lib/queuemanager.php
index 8f8c8f133..9fdc80110 100644
--- a/lib/queuemanager.php
+++ b/lib/queuemanager.php
@@ -262,6 +262,9 @@ abstract class QueueManager extends IoManager
$this->connect('sms', 'SmsQueueHandler');
}
+ // Broadcasting profile updates to OMB remote subscribers
+ $this->connect('profile', 'ProfileQueueHandler');
+
// XMPP output handlers...
if (common_config('xmpp', 'enabled')) {
// Delivery prep, read by queuedaemon.php:
diff --git a/lib/router.php b/lib/router.php
index 987d0152e..abbce041d 100644
--- a/lib/router.php
+++ b/lib/router.php
@@ -247,6 +247,9 @@ class Router
$m->connect('group/:nickname/'.$v,
array('action' => $v.'group'),
array('nickname' => '[a-zA-Z0-9]+'));
+ $m->connect('group/:id/id/'.$v,
+ array('action' => $v.'group'),
+ array('id' => '[0-9]+'));
}
foreach (array('members', 'logo', 'rss', 'designsettings') as $n) {
@@ -668,7 +671,7 @@ class Router
foreach (array('subscriptions', 'subscribers',
'all', 'foaf', 'xrds',
- 'replies', 'microsummary') as $a) {
+ 'replies', 'microsummary', 'hcard') as $a) {
$m->connect($a,
array('action' => $a,
'nickname' => $nickname));
@@ -734,7 +737,7 @@ class Router
foreach (array('subscriptions', 'subscribers',
'nudge', 'all', 'foaf', 'xrds',
- 'replies', 'inbox', 'outbox', 'microsummary') as $a) {
+ 'replies', 'inbox', 'outbox', 'microsummary', 'hcard') as $a) {
$m->connect(':nickname/'.$a,
array('action' => $a),
array('nickname' => '[a-zA-Z0-9]{1,64}'));
diff --git a/lib/util.php b/lib/util.php
index 7fb2c6c4b..8381bc63c 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -134,7 +134,7 @@ function common_check_user($nickname, $password)
$authenticatedUser = false;
if (Event::handle('StartCheckPassword', array($nickname, $password, &$authenticatedUser))) {
- $user = User::staticGet('nickname', $nickname);
+ $user = User::staticGet('nickname', common_canonical_nickname($nickname));
if (!empty($user)) {
if (!empty($password)) { // never allow login with blank password
if (0 == strcmp(common_munge_password($password, $user->id),
@@ -1119,12 +1119,16 @@ function common_enqueue_notice($notice)
return true;
}
-function common_broadcast_profile($profile)
+/**
+ * Broadcast profile updates to OMB and other remote subscribers.
+ *
+ * Since this may be slow with a lot of subscribers or bad remote sites,
+ * this is run through the background queues if possible.
+ */
+function common_broadcast_profile(Profile $profile)
{
- // XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ
- require_once(INSTALLDIR.'/lib/omb.php');
- omb_broadcast_profile($profile);
- // XXX: Other broadcasts...?
+ $qm = QueueManager::get();
+ $qm->enqueue($profile, "profile");
return true;
}
@@ -1602,6 +1606,7 @@ function common_database_tablename($tablename)
*/
function common_shorten_url($long_url)
{
+ $long_url = trim($long_url);
$user = common_current_user();
if (empty($user)) {
// common current user does not find a user when called from the XMPP daemon
@@ -1616,7 +1621,7 @@ function common_shorten_url($long_url)
return $long_url;
}else{
//URL was shortened, so return the result
- return $shortenedUrl;
+ return trim($shortenedUrl);
}
}
@@ -1693,7 +1698,8 @@ function common_url_to_nickname($url)
# Strip starting, ending slashes
$path = preg_replace('@/$@', '', $parts['path']);
$path = preg_replace('@^/@', '', $path);
- if (strpos($path, '/') === false) {
+ $path = basename($path);
+ if ($path) {
return common_nicknamize($path);
}
}