diff options
-rw-r--r-- | classes/Notice.php | 10 | ||||
-rw-r--r-- | plugins/OStatus/OStatusPlugin.php | 23 | ||||
-rw-r--r-- | plugins/OStatus/actions/usersalmon.php | 6 | ||||
-rw-r--r-- | plugins/OStatus/lib/activity.php | 65 | ||||
-rw-r--r-- | plugins/OStatus/lib/salmonaction.php | 45 | ||||
-rw-r--r-- | plugins/OStatus/tests/ActivityParseTests.php | 11 |
6 files changed, 149 insertions, 11 deletions
diff --git a/classes/Notice.php b/classes/Notice.php index 8b8f90474..0051cf885 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -194,6 +194,7 @@ class Notice extends Memcached_DataObject */ static function saveNew($profile_id, $content, $source, $options=null) { $defaults = array('uri' => null, + 'url' => null, 'reply_to' => null, 'repeat_of' => null); @@ -256,9 +257,16 @@ class Notice extends Memcached_DataObject } $notice->content = $final; - $notice->rendered = common_render_content($final, $notice); + + if (!empty($rendered)) { + $notice->rendered = $rendered; + } else { + $notice->rendered = common_render_content($final, $notice); + } + $notice->source = $source; $notice->uri = $uri; + $notice->url = $url; // Handle repeat case diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 5081c4d98..29799b0dc 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -365,16 +365,21 @@ class OStatusPlugin extends Plugin * @param Notice $notice being favored * @return hook return value */ - function onEndFavorNotice($profile, Notice $notice) + function onEndFavorNotice(Profile $profile, Notice $notice) { - if ($profile instanceof User) { - // @fixme upstream function should clarify its parameters - $profile = $profile->getProfile(); + $user = User::staticGet('id', $profile->id); + + if (empty($user)) { + return true; } + $oprofile = Ostatus_profile::staticGet('profile_id', $notice->profile_id); + if ($oprofile) { $oprofile->notify($profile, ActivityVerb::FAVORITE, $notice); } + + return true; } /** @@ -386,10 +391,18 @@ class OStatusPlugin extends Plugin */ function onEndDisfavorNotice(Profile $profile, Notice $notice) { + $user = User::staticGet('id', $profile->id); + + if (empty($user)) { + return true; + } + $oprofile = Ostatus_profile::staticGet('profile_id', $notice->profile_id); + if ($oprofile) { $oprofile->notify($profile, ActivityVerb::UNFAVORITE, $notice); } - } + return true; + } } diff --git a/plugins/OStatus/actions/usersalmon.php b/plugins/OStatus/actions/usersalmon.php index 20c6c2942..12c74798f 100644 --- a/plugins/OStatus/actions/usersalmon.php +++ b/plugins/OStatus/actions/usersalmon.php @@ -87,8 +87,7 @@ class UsersalmonAction extends SalmonAction throw new ClientException("Not to anyone in reply to anything!"); } - $profile = $this->ensureProfile(); - // @fixme do something with the post + $this->saveNotice(); } /** @@ -101,7 +100,8 @@ class UsersalmonAction extends SalmonAction $oprofile = $this->ensureProfile(); if ($oprofile) { common_log(LOG_INFO, "Setting up subscription from remote {$oprofile->uri} to local {$this->user->nickname}"); - $oprofile->subscribeRemoteToLocal($this->user); + Subscription::start($oprofile->localProfile(), + $this->user->getProfile()); } else { common_log(LOG_INFO, "Can't set up subscription from remote; missing profile."); } diff --git a/plugins/OStatus/lib/activity.php b/plugins/OStatus/lib/activity.php index 7563488b7..5f174d86f 100644 --- a/plugins/OStatus/lib/activity.php +++ b/plugins/OStatus/lib/activity.php @@ -183,6 +183,8 @@ class ActivityObject const TITLE = 'title'; const SUMMARY = 'summary'; const CONTENT = 'content'; + const TYPE = 'type'; + const SRC = 'src'; const ID = 'id'; const SOURCE = 'source'; @@ -199,7 +201,7 @@ class ActivityObject public $link; public $source; - /** + /** * Constructor * * This probably needs to be refactored @@ -243,10 +245,11 @@ class ActivityObject $this->id = $this->_childContent($element, self::ID); $this->title = $this->_childContent($element, self::TITLE); $this->summary = $this->_childContent($element, self::SUMMARY); - $this->content = $this->_childContent($element, self::CONTENT); $this->source = $this->_getSource($element); + $this->content = $this->_getContent($element); + $this->link = ActivityUtils::getPermalink($element); // XXX: grab PoCo stuff @@ -284,6 +287,64 @@ class ActivityObject } } + /** + * Get the content of an atom:entry-like object + * + * @param DOMElement $element The element to examine. + * + * @return string unencoded HTML content of the element, like "This -< is <b>HTML</b>." + * + * @todo handle remote content + * @todo handle embedded XML mime types + * @todo handle base64-encoded non-XML and non-text mime types + */ + + private function _getContent($element) + { + $contentEl = ActivityUtils::child($element, self::CONTENT); + + if (!empty($contentEl)) { + + $src = $contentEl->getAttribute(self::SRC); + + if (!empty($src)) { + throw new ClientException(_("Can't handle remote content yet.")); + } + + $type = $contentEl->getAttribute(self::TYPE); + + // slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3 + + if ($type == 'text') { + return $contentEl->textContent; + } else if ($type == 'html') { + $text = $contentEl->textContent; + return htmlspecialchars_decode($text, ENT_QUOTES); + } else if ($type == 'xhtml') { + $divEl = ActivityUtils::child($contentEl, 'div'); + if (empty($divEl)) { + return null; + } + $doc = $divEl->ownerDocument; + $text = ''; + $children = $divEl->childNodes; + + for ($i = 0; $i < $children->length; $i++) { + $child = $children->item($i); + $text .= $doc->saveXML($child); + } + return trim($text); + } else if (in_array(array('text/xml', 'application/xml'), $type) || + preg_match('#(+|/)xml$#', $type)) { + throw new ClientException(_("Can't handle embedded XML content yet.")); + } else if (strncasecmp($type, 'text/', 5)) { + return $contentEl->textContent; + } else { + throw new ClientException(_("Can't handle embedded Base64 content yet.")); + } + } + } + static function fromNotice($notice) { $object = new ActivityObject(); diff --git a/plugins/OStatus/lib/salmonaction.php b/plugins/OStatus/lib/salmonaction.php index c83890507..41e8322e8 100644 --- a/plugins/OStatus/lib/salmonaction.php +++ b/plugins/OStatus/lib/salmonaction.php @@ -231,4 +231,49 @@ class SalmonAction extends Action return null; } } + + function saveNotice() + { + $oprofile = $this->ensureProfile(); + + // Get (safe!) HTML and text versions of the content + + require_once(INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php'); + + $html = $this->act->object->content; + + $rendered = HTMLPurifier::purify($html); + $content = html_entity_decode(strip_tags($rendered)); + + $options = array('is_local' => Notice::REMOTE_OMB, + 'uri' => $this->act->object->id, + 'url' => $this->act->object->link, + 'rendered' => $rendered); + + if (!empty($this->act->context->location)) { + $options['lat'] = $location->lat; + $options['lon'] = $location->lon; + if ($location->location_id) { + $options['location_ns'] = $location->location_ns; + $options['location_id'] = $location->location_id; + } + } + + if (!empty($this->act->context->replyToID)) { + $orig = Notice::staticGet('uri', + $this->act->context->replyToID); + if (!empty($orig)) { + $options['reply_to'] = $orig->id; + } + } + + if (!empty($this->act->time)) { + $options['created'] = common_sql_time($this->act->time); + } + + return Notice::saveNew($oprofile->profile_id, + $content, + 'ostatus+salmon', + $options); + } } diff --git a/plugins/OStatus/tests/ActivityParseTests.php b/plugins/OStatus/tests/ActivityParseTests.php index 35b4b0f9d..d7305dede 100644 --- a/plugins/OStatus/tests/ActivityParseTests.php +++ b/plugins/OStatus/tests/ActivityParseTests.php @@ -22,8 +22,15 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase $act = new Activity($dom->documentElement); $this->assertFalse(empty($act)); + $this->assertEquals($act->time, 1243860840); $this->assertEquals($act->verb, ActivityVerb::POST); + + $this->assertFalse(empty($act->object)); + $this->assertEquals($act->object->title, 'Punctuation Changeset'); + $this->assertEquals($act->object->type, 'http://versioncentral.example.org/activity/changeset'); + $this->assertEquals($act->object->summary, 'Fixing punctuation because it makes it more readable.'); + $this->assertEquals($act->object->id, 'tag:versioncentral.example.org,2009:/change/1643245'); } public function testExample3() @@ -84,6 +91,10 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase $this->assertEquals('http://example.net/conversation/11', $act->context->conversation); $this->assertEquals(array('http://example.net/user/1'), $act->context->attention); + $this->assertFalse(empty($act->object)); + $this->assertEquals($act->object->content, + '@<span class="vcard"><a href="http://example.net/user/1" class="url"><span class="fn nickname">evan</span></a></span> now is the time for all good men to come to the aid of their country. #<span class="tag"><a href="http://example.net/tag/thetime" rel="tag">thetime</a></span>'); + $this->assertFalse(empty($act->actor)); } } |