summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-03-21 16:28:56 -0700
committerBrion Vibber <brion@pobox.com>2010-03-21 16:28:56 -0700
commitbe7efe750469312ad57815d20692bb5f5832ae94 (patch)
treee347dd8c0b5d74cbdff419a348eb303369280a93 /lib
parente458e9fe6352df6063079979b20a6924f97198f4 (diff)
parentfcb614d0eb1f98bf8704654ed06e1f9d9733d359 (diff)
Merge branch 'testing' into 0.9.x
Diffstat (limited to 'lib')
-rw-r--r--lib/activity.php63
-rw-r--r--lib/activityobject.php60
-rw-r--r--lib/activityutils.php22
-rw-r--r--lib/atomcategory.php77
4 files changed, 165 insertions, 57 deletions
diff --git a/lib/activity.php b/lib/activity.php
index b1744e68f..bd1d5d56c 100644
--- a/lib/activity.php
+++ b/lib/activity.php
@@ -238,17 +238,17 @@ class Activity
$this->time = strtotime($pubDateEl->textContent);
}
- $authorEl = $this->_child($item, self::AUTHOR, self::RSS);
-
- if (!empty($authorEl)) {
+ if ($authorEl = $this->_child($item, self::AUTHOR, self::RSS)) {
$this->actor = ActivityObject::fromRssAuthor($authorEl);
+ } else if ($dcCreatorEl = $this->_child($item, self::CREATOR, self::DC)) {
+ $this->actor = ActivityObject::fromDcCreator($dcCreatorEl);
+ } else if ($posterousEl = $this->_child($item, ActivityObject::AUTHOR, ActivityObject::POSTEROUS)) {
+ // Special case for Posterous.com
+ $this->actor = ActivityObject::fromPosterousAuthor($posterousEl);
+ } else if (!empty($channel)) {
+ $this->actor = ActivityObject::fromRssChannel($channel);
} else {
- $dcCreatorEl = $this->_child($item, self::CREATOR, self::DC);
- if (!empty($dcCreatorEl)) {
- $this->actor = ActivityObject::fromDcCreator($dcCreatorEl);
- } else if (!empty($channel)) {
- $this->actor = ActivityObject::fromRssChannel($channel);
- }
+ // No actor!
}
$this->title = ActivityUtils::childContent($item, ActivityObject::TITLE, self::RSS);
@@ -362,48 +362,3 @@ class Activity
}
}
-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/activityobject.php b/lib/activityobject.php
index b1e9071ed..0a358ccab 100644
--- a/lib/activityobject.php
+++ b/lib/activityobject.php
@@ -80,6 +80,13 @@ class ActivityObject
const URI = 'uri';
const EMAIL = 'email';
+ const POSTEROUS = 'http://posterous.com/help/rss/1.0';
+ const AUTHOR = 'author';
+ const USERIMAGE = 'userImage';
+ const PROFILEURL = 'profileUrl';
+ const NICKNAME = 'nickName';
+ const DISPLAYNAME = 'displayName';
+
public $element;
public $type;
public $id;
@@ -149,7 +156,11 @@ class ActivityObject
{
$this->type = self::PERSON; // XXX: is this fair?
$this->title = $this->_childContent($element, self::NAME);
- $this->id = $this->_childContent($element, self::URI);
+
+ $id = $this->_childContent($element, self::URI);
+ if (ActivityUtils::validateUri($id)) {
+ $this->id = $id;
+ }
if (empty($this->id)) {
$email = $this->_childContent($element, self::EMAIL);
@@ -162,6 +173,15 @@ class ActivityObject
private function _fromAtomEntry($element)
{
+ if ($element->localName == 'actor') {
+ // Old-fashioned <activity:actor>...
+ // First pull anything from <author>, then we'll add on top.
+ $author = ActivityUtils::child($element->parentNode, 'author');
+ if ($author) {
+ $this->_fromAuthor($author);
+ }
+ }
+
$this->type = $this->_childContent($element, Activity::OBJECTTYPE,
Activity::SPEC);
@@ -169,7 +189,11 @@ class ActivityObject
$this->type = ActivityObject::NOTE;
}
- $this->id = $this->_childContent($element, self::ID);
+ $id = $this->_childContent($element, self::ID);
+ if (ActivityUtils::validateUri($id)) {
+ $this->id = $id;
+ }
+
$this->summary = ActivityUtils::childHtmlContent($element, self::SUMMARY);
$this->content = ActivityUtils::getContent($element);
@@ -290,9 +314,39 @@ class ActivityObject
$imageEl = ActivityUtils::child($el, Activity::IMAGE, Activity::RSS);
if (!empty($imageEl)) {
- $obj->avatarLinks[] = ActivityUtils::childContent($imageEl, Activity::URL, Activity::RSS);
+ $url = ActivityUtils::childContent($imageEl, Activity::URL, Activity::RSS);
+ $al = new AvatarLink();
+ $al->url = $url;
+ $obj->avatarLinks[] = $al;
+ }
+
+ return $obj;
+ }
+
+ public static function fromPosterousAuthor($el)
+ {
+ $obj = new ActivityObject();
+
+ $obj->type = ActivityObject::PERSON; // @fixme any others...?
+
+ $userImage = ActivityUtils::childContent($el, self::USERIMAGE, self::POSTEROUS);
+
+ if (!empty($userImage)) {
+ $al = new AvatarLink();
+ $al->url = $userImage;
+ $obj->avatarLinks[] = $al;
}
+ $obj->link = ActivityUtils::childContent($el, self::PROFILEURL, self::POSTEROUS);
+ $obj->id = $obj->link;
+
+ $obj->poco = new PoCo();
+
+ $obj->poco->preferredUsername = ActivityUtils::childContent($el, self::NICKNAME, self::POSTEROUS);
+ $obj->poco->displayName = ActivityUtils::childContent($el, self::DISPLAYNAME, self::POSTEROUS);
+
+ $obj->title = $obj->poco->displayName;
+
return $obj;
}
diff --git a/lib/activityutils.php b/lib/activityutils.php
index c85a3db55..a7e99fb11 100644
--- a/lib/activityutils.php
+++ b/lib/activityutils.php
@@ -240,4 +240,26 @@ class ActivityUtils
throw new ClientException(_("Can't handle embedded Base64 content yet."));
}
}
+
+ /**
+ * Is this a valid URI for remote profile/notice identification?
+ * Does not have to be a resolvable URL.
+ * @param string $uri
+ * @return boolean
+ */
+ static function validateUri($uri)
+ {
+ if (Validate::uri($uri)) {
+ return true;
+ }
+
+ // Possibly an upstream bug; tag: URIs aren't validated properly
+ // unless you explicitly ask for them. All other schemes are accepted
+ // for basic URI validation without asking.
+ if (Validate::uri($uri, array('allowed_scheme' => array('tag')))) {
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/lib/atomcategory.php b/lib/atomcategory.php
new file mode 100644
index 000000000..4cc3b4f4d
--- /dev/null
+++ b/lib/atomcategory.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * 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 Feed
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @author Zach Copley <zach@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+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();
+ }
+}