From ac6d86c0db419ebeb849b9dc53ce2d7ce006e143 Mon Sep 17 00:00:00 2001 From: Aaron Parecki Date: Sun, 28 Feb 2016 09:03:25 -0800 Subject: [PATCH] includes nested h-cite and other objects if a property such as `in-reply-to` is an h-cite, the URL is still returned as the `in-reply-to` value, and the h-cite object is available in a different part of the response. closes #6 --- controllers/Parse.php | 4 +- lib/Formats/Mf2.php | 46 +++++++++++++++-- tests/ParseTest.php | 51 +++++++++++++++++++ .../source.example.com/person-tag-is-h-card | 17 +++++++ .../data/source.example.com/person-tag-is-url | 15 ++++++ tests/data/source.example.com/reply-is-h-cite | 19 +++++++ tests/data/source.example.com/reply-is-url | 15 ++++++ 7 files changed, 159 insertions(+), 8 deletions(-) create mode 100644 tests/data/source.example.com/person-tag-is-h-card create mode 100644 tests/data/source.example.com/person-tag-is-url create mode 100644 tests/data/source.example.com/reply-is-h-cite create mode 100644 tests/data/source.example.com/reply-is-url diff --git a/controllers/Parse.php b/controllers/Parse.php index 3e89f8f..4dc88a6 100644 --- a/controllers/Parse.php +++ b/controllers/Parse.php @@ -116,9 +116,7 @@ class Parse { if($mf2 && count($mf2['items']) > 0) { $data = Formats\Mf2::parse($mf2, $url, $this->http); if($data) { - return $this->respond($response, 200, [ - 'data' => $data, - ]); + return $this->respond($response, 200, $data); } } diff --git a/lib/Formats/Mf2.php b/lib/Formats/Mf2.php index e10eac5..731e4f2 100644 --- a/lib/Formats/Mf2.php +++ b/lib/Formats/Mf2.php @@ -27,7 +27,7 @@ class Mf2 { } // Otherwise check for an h-entry - if(in_array('h-entry', $item['type'])) { + if(in_array('h-entry', $item['type']) || in_array('h-cite', $item['type'])) { return self::parseHEntry($mf2, $http); } } @@ -45,6 +45,7 @@ class Mf2 { 'photo' => null ] ]; + $refs = []; $item = $mf2['items'][0]; @@ -56,7 +57,7 @@ class Mf2 { } // Always arrays - $properties = ['photo','video','syndication','in-reply-to','like-of','repost-of','category']; + $properties = ['photo','video','syndication']; foreach($properties as $p) { if(array_key_exists($p, $item['properties'])) { $data[$p] = []; @@ -69,6 +70,27 @@ class Mf2 { } } + // Always returned as arrays, and may also create external references + $properties = ['in-reply-to','like-of','repost-of','category']; + foreach($properties as $p) { + if(array_key_exists($p, $item['properties'])) { + $data[$p] = []; + foreach($item['properties'][$p] as $v) { + if(is_string($v)) + $data[$p][] = $v; + elseif(self::isMicroformat($v) && ($u=self::getPlaintext($v, 'url'))) { + $data[$p][] = $u; + // parse the object and put the result in the "refs" object + $ref = self::parse(['items'=>[$v]], $u, $http); + if($ref) { + $refs[$u] = $ref['data']; + } + } + } + } + } + + // Determine if the name is distinct from the content $name = self::getPlaintext($item, 'name'); $content = null; @@ -114,7 +136,15 @@ class Mf2 { $data['author'] = self::findAuthor($mf2, $item, $http); - return $data; + $response = [ + 'data' => $data + ]; + + if(count($refs)) { + $response['refs'] = $refs; + } + + return $response; } private static function parseHFeed($mf2, $http) { @@ -130,7 +160,9 @@ class Mf2 { 'todo' => 'Not yet implemented. Please see https://github.com/aaronpk/XRay/issues/1' ]; - return $data; + return [ + 'data' => $data + ]; } private static function parseHCard($item, $http, $authorURL=false) { @@ -159,7 +191,11 @@ class Mf2 { } } - return $data; + $response = [ + 'data' => $data + ]; + + return $response; } private static function findAuthor($mf2, $item, $http) { diff --git a/tests/ParseTest.php b/tests/ParseTest.php index b96721e..42283da 100644 --- a/tests/ParseTest.php +++ b/tests/ParseTest.php @@ -128,4 +128,55 @@ class ParseTest extends PHPUnit_Framework_TestCase { $this->assertEquals('unknown', $data->data->type); } + public function testReplyIsURL() { + $url = 'http://source.example.com/reply-is-url'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('http://example.com/100', $data['data']['in-reply-to'][0]); + } + + public function testReplyIsHCite() { + $url = 'http://source.example.com/reply-is-h-cite'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('http://example.com/100', $data['data']['in-reply-to'][0]); + $this->assertArrayHasKey('http://example.com/100', $data['refs']); + $this->assertEquals('Example Post', $data['refs']['http://example.com/100']['name']); + $this->assertEquals('http://example.com/100', $data['refs']['http://example.com/100']['url']); + } + + public function testPersonTagIsURL() { + $url = 'http://source.example.com/person-tag-is-url'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('http://alice.example.com/', $data['data']['category'][0]); + } + + public function testPersonTagIsHCard() { + $url = 'http://source.example.com/person-tag-is-h-card'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('http://alice.example.com/', $data['data']['category'][0]); + $this->assertArrayHasKey('http://alice.example.com/', $data['refs']); + $this->assertEquals('card', $data['refs']['http://alice.example.com/']['type']); + $this->assertEquals('http://alice.example.com/', $data['refs']['http://alice.example.com/']['url']); + $this->assertEquals('Alice', $data['refs']['http://alice.example.com/']['name']); + } + } \ No newline at end of file diff --git a/tests/data/source.example.com/person-tag-is-h-card b/tests/data/source.example.com/person-tag-is-h-card new file mode 100644 index 0000000..9722724 --- /dev/null +++ b/tests/data/source.example.com/person-tag-is-h-card @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +Server: Apache +Date: Wed, 09 Dec 2015 03:29:14 GMT +Content-Type: text/html; charset=utf-8 +Connection: keep-alive + + + + Test + + +

Hello World

+
+ Alice +
+ + diff --git a/tests/data/source.example.com/person-tag-is-url b/tests/data/source.example.com/person-tag-is-url new file mode 100644 index 0000000..f6c0d3f --- /dev/null +++ b/tests/data/source.example.com/person-tag-is-url @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: Apache +Date: Wed, 09 Dec 2015 03:29:14 GMT +Content-Type: text/html; charset=utf-8 +Connection: keep-alive + + + + Test + + +

Hello World

+ Alice + + diff --git a/tests/data/source.example.com/reply-is-h-cite b/tests/data/source.example.com/reply-is-h-cite new file mode 100644 index 0000000..f12431e --- /dev/null +++ b/tests/data/source.example.com/reply-is-h-cite @@ -0,0 +1,19 @@ +HTTP/1.1 200 OK +Server: Apache +Date: Wed, 09 Dec 2015 03:29:14 GMT +Content-Type: text/html; charset=utf-8 +Connection: keep-alive + + + + Test + + +
+ Example Post + Author + permalink +
+

This page has a link to target.example.com and some formatted text.

+ + diff --git a/tests/data/source.example.com/reply-is-url b/tests/data/source.example.com/reply-is-url new file mode 100644 index 0000000..6ba5570 --- /dev/null +++ b/tests/data/source.example.com/reply-is-url @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: Apache +Date: Wed, 09 Dec 2015 03:29:14 GMT +Content-Type: text/html; charset=utf-8 +Connection: keep-alive + + + + Test + + + in reply to +

This page has a link to target.example.com and some formatted text.

+ +