-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
474 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace JDecool\JsonFeed\Reader; | ||
|
||
use InvalidArgumentException; | ||
use RuntimeException; | ||
|
||
class Reader | ||
{ | ||
/** @var ReaderInterface[] */ | ||
private $readers; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param ReaderInterface[] $readers | ||
*/ | ||
public function __construct(array $readers) | ||
{ | ||
$this->readers = $readers; | ||
} | ||
|
||
/** | ||
* Read feed from JSON | ||
* | ||
* @param string $json | ||
* @return \JDecool\JsonFeed\Feed | ||
*/ | ||
public function createFromJson($json) | ||
{ | ||
$content = json_decode($json, true); | ||
if (!is_array($content)) { | ||
throw new InvalidArgumentException('Invalid JSONFeed string'); | ||
} | ||
|
||
if (!isset($content['version'])) { | ||
throw new RuntimeException('JSONFeed version is not defined'); | ||
} | ||
|
||
if (!isset($this->readers[$content['version']])) { | ||
throw new RuntimeException(sprintf('No reader for version "%s"', $content['version'])); | ||
} | ||
|
||
return $this->readers[$content['version']]->readFromJson($json); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace JDecool\JsonFeed\Reader; | ||
|
||
use JDecool\JsonFeed\Versions; | ||
|
||
class ReaderBuilder | ||
{ | ||
/** | ||
* Builder a reader | ||
* | ||
* @return Reader | ||
*/ | ||
public function build() | ||
{ | ||
return new Reader([ | ||
Versions::VERSION_1 => Version1\FeedReader::create(), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace JDecool\JsonFeed\Reader; | ||
|
||
use JDecool\JsonFeed\Feed; | ||
|
||
interface ReaderInterface | ||
{ | ||
/** | ||
* Read feed from JSON | ||
* | ||
* @param string $json | ||
* @return Feed | ||
*/ | ||
public function readFromJson($json); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
<?php | ||
|
||
namespace JDecool\JsonFeed\Reader\Version1; | ||
|
||
use DateTime; | ||
use InvalidArgumentException; | ||
use JDecool\JsonFeed\Attachment; | ||
use JDecool\JsonFeed\Author; | ||
use JDecool\JsonFeed\Feed; | ||
use JDecool\JsonFeed\Hub; | ||
use JDecool\JsonFeed\Item; | ||
use JDecool\JsonFeed\Reader\ReaderInterface; | ||
use Symfony\Component\PropertyAccess\PropertyAccess; | ||
|
||
class FeedReader implements ReaderInterface | ||
{ | ||
/** @var \Symfony\Component\PropertyAccess\PropertyAccessor */ | ||
private $accessor; | ||
|
||
/** @var FeedReader */ | ||
private static $instance; | ||
|
||
/** | ||
* Create reader instance | ||
* | ||
* @return FeedReader | ||
*/ | ||
public static function create() | ||
{ | ||
if (null === self::$instance) { | ||
self::$instance = new self; | ||
} | ||
|
||
return self::$instance; | ||
} | ||
|
||
/** | ||
* Constructor | ||
*/ | ||
private function __construct() | ||
{ | ||
$this->accessor = PropertyAccess::createPropertyAccessor(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function readFromJson($json) | ||
{ | ||
$content = json_decode($json, true); | ||
if (!is_array($content)) { | ||
throw new InvalidArgumentException('Invalid JSONFeed string'); | ||
} | ||
|
||
return $this->readFeedNode($content); | ||
} | ||
|
||
/** | ||
* Browse feed node | ||
* | ||
* @param array $content | ||
* @return Feed | ||
*/ | ||
private function readFeedNode(array $content) | ||
{ | ||
$feed = new Feed(''); | ||
|
||
foreach ($content as $key => $value) { | ||
if ('version' === $key) { | ||
continue; | ||
} | ||
|
||
switch ($key) { | ||
case 'author': | ||
$feed->setAuthor($this->readAuthorNode($value)); | ||
break; | ||
|
||
case 'hubs': | ||
$feed->setHubs(array_map([$this, 'readHubNode'], $value)); | ||
break; | ||
|
||
case 'items': | ||
$feed->setItems(array_map([$this, 'readItemNode'], $value)); | ||
break; | ||
|
||
default: | ||
$this->accessor->setValue($feed, $key, $value); | ||
} | ||
} | ||
|
||
return $feed; | ||
} | ||
|
||
/** | ||
* Browse item node | ||
* | ||
* @param array $content | ||
* @return Item | ||
*/ | ||
private function readItemNode(array $content) | ||
{ | ||
$id = isset($content['id']) ? $content['id'] : ''; | ||
|
||
$item = new Item($id); | ||
foreach ($content as $key => $value) { | ||
if ('id' === $key) { | ||
continue; | ||
} | ||
|
||
switch ($key) { | ||
case 'attachments': | ||
$item->setAttachments(array_map([$this, 'readAttachmentNode'], $value)); | ||
break; | ||
|
||
case 'author': | ||
$item->setAuthor($this->readAuthorNode($value)); | ||
break; | ||
|
||
case 'date_published': | ||
case 'date_modified': | ||
$this->accessor->setValue($item, $key, new DateTime($value)); | ||
break; | ||
|
||
default: | ||
$this->accessor->setValue($item, $key, $value); | ||
} | ||
} | ||
|
||
return $item; | ||
} | ||
|
||
/** | ||
* Browse author node | ||
* | ||
* @param array $content | ||
* @return Author | ||
*/ | ||
private function readAuthorNode(array $content) | ||
{ | ||
$name = (isset($content['name'])) ? $content['name'] : ''; | ||
|
||
$author = new Author($name); | ||
foreach ($content as $key => $value) { | ||
if ('name' === $key) { | ||
continue; | ||
} | ||
|
||
$this->accessor->setValue($author, $key, $value); | ||
} | ||
|
||
return $author; | ||
} | ||
|
||
/** | ||
* Browse hub node | ||
* | ||
* @param array $content | ||
* @return Hub | ||
*/ | ||
private function readHubNode(array $content) | ||
{ | ||
$type = isset($content['type']) ? $content['type'] : ''; | ||
$url = isset($content['url']) ? $content['url'] : ''; | ||
|
||
return new Hub($type, $url); | ||
} | ||
|
||
/** | ||
* Browse attachment node | ||
* | ||
* @param array $content | ||
* @return Attachment | ||
*/ | ||
private function readAttachmentNode(array $content) | ||
{ | ||
$url = isset($content['url']) ? $content['url'] : ''; | ||
$mimeType = isset($content['mime_type']) ? $content['mime_type'] : ''; | ||
|
||
$attachment = new Attachment($url, $mimeType); | ||
foreach ($content as $key => $value) { | ||
switch ($key) { | ||
case 'size_in_bytes': | ||
$attachment->setSize($value); | ||
break; | ||
|
||
case 'duration_in_seconds': | ||
$attachment->setDuration($value); | ||
break; | ||
} | ||
} | ||
|
||
return $attachment; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace JDecool\Test\JsonFeed\Reader; | ||
|
||
use JDecool\JsonFeed\Reader\ReaderBuilder; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ReaderBuilderTest extends TestCase | ||
{ | ||
public function testBuilder() | ||
{ | ||
$builder = new ReaderBuilder(); | ||
|
||
$this->assertInstanceOf('JDecool\JsonFeed\Reader\Reader', $builder->build()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
namespace JDecool\Test\JsonFeed\Reader; | ||
|
||
use JDecool\JsonFeed\Reader\Reader; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ReaderTest extends TestCase | ||
{ | ||
public function testCreateFromJson() | ||
{ | ||
$json = <<<JSON | ||
{ | ||
"version": "foo", | ||
"title": "My Example Feed" | ||
} | ||
JSON; | ||
|
||
$feedReader = $this->getMockBuilder('JDecool\JsonFeed\Reader\ReaderInterface')->getMock(); | ||
$feedReader->expects($this->once()) | ||
->method('readFromJson'); | ||
|
||
$reader = new Reader([ | ||
'foo' => $feedReader, | ||
]); | ||
|
||
$reader->createFromJson($json); | ||
} | ||
|
||
/** | ||
* @expectedException RuntimeException | ||
* @expectedExceptionMessage No reader for version "foo" | ||
*/ | ||
public function testCreateFromJsonWithInvalidReader() | ||
{ | ||
$json = <<<JSON | ||
{ | ||
"version": "foo", | ||
"title": "My Example Feed" | ||
} | ||
JSON; | ||
|
||
$reader = new Reader([]); | ||
$reader->createFromJson($json); | ||
} | ||
|
||
/** | ||
* @expectedException InvalidArgumentException | ||
* @expectedExceptionMessage Invalid JSONFeed string | ||
*/ | ||
public function testCreateFromJsonWithInvalidString() | ||
{ | ||
$json = <<<JSON | ||
{ | ||
"version": "foo", | ||
"title": "My Example Feed", | ||
} | ||
JSON; | ||
|
||
$reader = new Reader([]); | ||
$reader->createFromJson($json); | ||
} | ||
|
||
/** | ||
* @expectedException RuntimeException | ||
* @expectedExceptionMessage JSONFeed version is not defined | ||
*/ | ||
public function testCreateFromJsonWithoutVersion() | ||
{ | ||
$json = <<<JSON | ||
{ | ||
"title": "My Example Feed" | ||
} | ||
JSON; | ||
|
||
$reader = new Reader([]); | ||
$reader->createFromJson($json); | ||
} | ||
} |
Oops, something went wrong.