mirror of
https://github.com/Chouchen/ShikiryuRSS.git
synced 2024-11-22 07:48:51 +01:00
✨ Finishes Builders
This commit is contained in:
parent
a6a31e18e1
commit
317d9e37e8
98
src/Builder/ChannelBuilder.php
Normal file
98
src/Builder/ChannelBuilder.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shikiryu\SRSS\Builder;
|
||||||
|
|
||||||
|
use DOMElement;
|
||||||
|
use Shikiryu\SRSS\Entity\Channel;
|
||||||
|
|
||||||
|
class ChannelBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
private \DOMDocument $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DOMDocument $document
|
||||||
|
*/
|
||||||
|
public function __construct(\DOMDocument $document)
|
||||||
|
{
|
||||||
|
$this->document = $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Shikiryu\SRSS\Entity\Channel $channel
|
||||||
|
*
|
||||||
|
* @return \DOMElement|false
|
||||||
|
* @throws \DOMException
|
||||||
|
*/
|
||||||
|
public function build(Channel $channel)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('channel');
|
||||||
|
foreach (array_filter($channel->toArray(), static fn($el) => !empty($el)) as $name => $value) {
|
||||||
|
if ($name === 'category') {
|
||||||
|
/** @var \Shikiryu\SRSS\Entity\Channel\Category $category */
|
||||||
|
foreach ($value as $category) {
|
||||||
|
$node->appendChild($this->buildCategory($category));
|
||||||
|
}
|
||||||
|
} elseif ($name === 'cloud') {
|
||||||
|
$node->appendChild($this->buildCloud($value));
|
||||||
|
} elseif ($name === 'image') {
|
||||||
|
$node->appendChild($this->buildImage($value));
|
||||||
|
} else {
|
||||||
|
$new_node = $this->document->createElement($name, $value);
|
||||||
|
$node->appendChild($new_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Shikiryu\SRSS\Entity\Channel\Category $category
|
||||||
|
*
|
||||||
|
* @return bool|\DOMElement
|
||||||
|
* @throws \DOMException
|
||||||
|
*/
|
||||||
|
private function buildCategory(Channel\Category $category): bool|DOMElement
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('category', $category->value);
|
||||||
|
$node->setAttribute('domain', $category->domain);
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Shikiryu\SRSS\Entity\Channel\Cloud $cloud
|
||||||
|
*
|
||||||
|
* @return \DOMElement|false
|
||||||
|
* @throws \DOMException
|
||||||
|
*/
|
||||||
|
private function buildCloud(Channel\Cloud $cloud)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('cloud');
|
||||||
|
foreach (get_object_vars($cloud) as $name => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$node->setAttribute($name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Shikiryu\SRSS\Entity\Channel\Image $image
|
||||||
|
*
|
||||||
|
* @return \DOMElement|false
|
||||||
|
* @throws \DOMException
|
||||||
|
*/
|
||||||
|
private function buildImage(Channel\Image $image)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('image');
|
||||||
|
foreach (get_object_vars($image) as $name => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$node->appendChild($this->document->createElement($name, $value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
105
src/Builder/ItemBuilder.php
Normal file
105
src/Builder/ItemBuilder.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shikiryu\SRSS\Builder;
|
||||||
|
|
||||||
|
use Shikiryu\SRSS\Entity\Item;
|
||||||
|
use Shikiryu\SRSS\Entity\Media\Content;
|
||||||
|
|
||||||
|
class ItemBuilder
|
||||||
|
{
|
||||||
|
private \DOMDocument $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DOMDocument $document
|
||||||
|
*/
|
||||||
|
public function __construct(\DOMDocument $document)
|
||||||
|
{
|
||||||
|
$this->document = $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Shikiryu\SRSS\Entity\Item $item
|
||||||
|
*
|
||||||
|
* @return \DOMElement|false
|
||||||
|
* @throws \DOMException
|
||||||
|
*/
|
||||||
|
public function build(Item $item): bool|\DOMElement
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('item');
|
||||||
|
|
||||||
|
foreach (array_filter($item->toArray()) as $name => $value) {
|
||||||
|
if ($name === 'category') {
|
||||||
|
/** @var \Shikiryu\SRSS\Entity\Item\Category $category */
|
||||||
|
foreach ($value as $category) {
|
||||||
|
$node->appendChild($this->buildCategory($category));
|
||||||
|
}
|
||||||
|
} elseif ($name === 'medias') {
|
||||||
|
$group = null;
|
||||||
|
if (count($value) > 1) {
|
||||||
|
$group = $node->appendChild($this->document->createElement('media:group'));
|
||||||
|
}
|
||||||
|
foreach ($value as $media) {
|
||||||
|
if (null === $group) {
|
||||||
|
$node->appendChild($this->buildMedia($media));
|
||||||
|
} else {
|
||||||
|
$group->appendChild($this->buildMedia($media));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($group !== null) {
|
||||||
|
$node->appendChild($group);
|
||||||
|
}
|
||||||
|
} elseif ($name === 'enclosure') {
|
||||||
|
$node->appendChild($this->buildEnclosure($value));
|
||||||
|
} elseif ($name === 'source') {
|
||||||
|
$node->appendChild($this->buildSource($value));
|
||||||
|
} else {
|
||||||
|
$new_node = $this->document->createElement($name, $value);
|
||||||
|
$node->appendChild($new_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildCategory(Item\Category $category)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('category', $category->value);
|
||||||
|
$node->setAttribute('domain', $category->domain);
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildEnclosure(Item\Enclosure $enclosure)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('enclosure');
|
||||||
|
foreach (get_object_vars($enclosure) as $name => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$node->setAttribute($name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildSource(Item\Source $source)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('source', $source->value);
|
||||||
|
$node->setAttribute('url', $source->url);
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildMedia(Content $media)
|
||||||
|
{
|
||||||
|
$node = $this->document->createElement('media:content');
|
||||||
|
foreach (get_object_vars($media) as $name => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$node->setAttribute($name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3,9 +3,6 @@
|
|||||||
namespace Shikiryu\SRSS\Builder;
|
namespace Shikiryu\SRSS\Builder;
|
||||||
|
|
||||||
use DOMDocument;
|
use DOMDocument;
|
||||||
use DOMElement;
|
|
||||||
use Shikiryu\SRSS\Entity\Channel;
|
|
||||||
use Shikiryu\SRSS\Entity\Item;
|
|
||||||
use Shikiryu\SRSS\Exception\DOMBuilderException;
|
use Shikiryu\SRSS\Exception\DOMBuilderException;
|
||||||
use Shikiryu\SRSS\SRSS;
|
use Shikiryu\SRSS\SRSS;
|
||||||
|
|
||||||
@ -20,13 +17,16 @@ class SRSSBuilder extends DomDocument
|
|||||||
$root = $this->createElement('rss');
|
$root = $this->createElement('rss');
|
||||||
|
|
||||||
$root->setAttribute('version', '2.0');
|
$root->setAttribute('version', '2.0');
|
||||||
$channel = $this->createElement('channel');
|
|
||||||
|
|
||||||
$srss->channel->generator = 'Shikiryu RSS';
|
$srss->channel->generator = 'Shikiryu RSS';
|
||||||
|
|
||||||
$this->appendChannelToDom($srss->channel, $channel);
|
$channel_builder = new ChannelBuilder($this);
|
||||||
|
$channel = $channel_builder->build($srss->channel);
|
||||||
|
|
||||||
$this->appendItemsToDom($srss->items, $channel);
|
$item_builder = new ItemBuilder($this);
|
||||||
|
foreach ($srss->items as $item) {
|
||||||
|
$channel->appendChild($item_builder->build($item));
|
||||||
|
}
|
||||||
|
|
||||||
$root->appendChild($channel);
|
$root->appendChild($channel);
|
||||||
$this->appendChild($root);
|
$this->appendChild($root);
|
||||||
@ -62,29 +62,4 @@ class SRSSBuilder extends DomDocument
|
|||||||
->buildRSS($srss)
|
->buildRSS($srss)
|
||||||
->saveXml();
|
->saveXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function appendChannelToDom(Channel $channel, DOMElement $node): void
|
|
||||||
{
|
|
||||||
foreach (array_filter($channel->toArray(), static fn($el) => !empty($el)) as $name => $value) {
|
|
||||||
$new_node = $this->createElement($name, $value);
|
|
||||||
$node->appendChild($new_node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function appendItemsToDom(array $items, DOMElement $channel): void
|
|
||||||
{
|
|
||||||
foreach ($items as $item) {
|
|
||||||
$this->appendItemToDom($item, $channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function appendItemToDom(Item $item, DOMElement $channel): void
|
|
||||||
{
|
|
||||||
$itemNode = $this->createElement('item');
|
|
||||||
foreach (array_filter($item->toArray()) as $name => $value) {
|
|
||||||
$new_node = $this->createElement($name, $value);
|
|
||||||
$itemNode->appendChild($new_node);
|
|
||||||
}
|
|
||||||
$channel->appendChild($itemNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -126,9 +126,13 @@ class SRSS implements Iterator
|
|||||||
throw new PropertyNotFoundException(Channel::class, $name);
|
throw new PropertyNotFoundException(Channel::class, $name);
|
||||||
}
|
}
|
||||||
if ((new Validator())->isValidValueForObjectProperty($this->channel, $name, $val)) {
|
if ((new Validator())->isValidValueForObjectProperty($this->channel, $name, $val)) {
|
||||||
|
if (SRSSTools::getPropertyType(Channel::class, $name) === 'array') {
|
||||||
|
$this->channel->{$name}[] = $val;
|
||||||
|
} else {
|
||||||
$this->channel->{$name} = $val;
|
$this->channel->{$name} = $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getter of others attributes
|
* getter of others attributes
|
||||||
|
@ -4,9 +4,15 @@ namespace Shikiryu\SRSS;
|
|||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
use ReflectionProperty;
|
||||||
|
|
||||||
class SRSSTools
|
class SRSSTools
|
||||||
{
|
{
|
||||||
|
public static function getPropertyType($object, $property): ?string
|
||||||
|
{
|
||||||
|
$rp = new ReflectionProperty($object, $property);
|
||||||
|
return $rp->getType()?->getName();
|
||||||
|
}
|
||||||
public static function check($check, $flag)
|
public static function check($check, $flag)
|
||||||
{
|
{
|
||||||
return match ($flag) {
|
return match ($flag) {
|
||||||
|
@ -272,4 +272,9 @@ class Validator
|
|||||||
{
|
{
|
||||||
return in_array($value, ['sample', 'full', 'nonstop']);
|
return in_array($value, ['sample', 'full', 'nonstop']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function _validateEmail($value): bool
|
||||||
|
{
|
||||||
|
return filter_var($value, FILTER_VALIDATE_EMAIL);
|
||||||
|
}
|
||||||
}
|
}
|
101
tests/CompleteBuilderTest.php
Normal file
101
tests/CompleteBuilderTest.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Shikiryu\SRSS\Entity\Channel\Category;
|
||||||
|
use Shikiryu\SRSS\Entity\Channel\Cloud;
|
||||||
|
use Shikiryu\SRSS\Entity\Channel\Image;
|
||||||
|
use Shikiryu\SRSS\Entity\Item\Enclosure;
|
||||||
|
use Shikiryu\SRSS\Entity\Item\Source;
|
||||||
|
use Shikiryu\SRSS\SRSS;
|
||||||
|
|
||||||
|
class CompleteBuilderTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testBuildACompleteRSS()
|
||||||
|
{
|
||||||
|
$file = __DIR__ . '/resources/tmp/build/complete.rss';
|
||||||
|
$title = 'Test';
|
||||||
|
$link = 'https://example.org';
|
||||||
|
$description = 'My description is <a href="https://example.org">better</a>';
|
||||||
|
$language = 'en-us';
|
||||||
|
$copyright = 'Shikiryu';
|
||||||
|
$managingEditor = 'editor';
|
||||||
|
$webMaster = 'Shikiryu';
|
||||||
|
$pubDate = (new DateTime())->format(DATE_RSS);
|
||||||
|
$lastBuildDate = $pubDate;
|
||||||
|
$category = new Category();
|
||||||
|
$category->domain = $link;
|
||||||
|
$category->value = 'Test Category';
|
||||||
|
$generator = 'SRSS';
|
||||||
|
$docs = $link;
|
||||||
|
$cloud = new Cloud();
|
||||||
|
$cloud->domain = $link;
|
||||||
|
$cloud->port = 80;
|
||||||
|
$cloud->path = '/test';
|
||||||
|
$ttl = 3660;
|
||||||
|
$image = new Image();
|
||||||
|
$image->link = $link;
|
||||||
|
$image->title = 'title of image';
|
||||||
|
$rating = 'yes';
|
||||||
|
$textInput = 'ignore';
|
||||||
|
$skipDays = 'monday';
|
||||||
|
$skipHours = '8';
|
||||||
|
|
||||||
|
$srss = SRSS::create();
|
||||||
|
$srss->title = $title;
|
||||||
|
$srss->link = $link;
|
||||||
|
$srss->description = $description;
|
||||||
|
$srss->language = $language;
|
||||||
|
$srss->copyright = $copyright;
|
||||||
|
$srss->managingEditor = $managingEditor;
|
||||||
|
$srss->webMaster = $webMaster;
|
||||||
|
$srss->pubDate = $pubDate;
|
||||||
|
$srss->lastBuildDate = $lastBuildDate;
|
||||||
|
$srss->category = $category;
|
||||||
|
$srss->generator = $generator;
|
||||||
|
$srss->docs = $docs;
|
||||||
|
$srss->cloud = $cloud;
|
||||||
|
$srss->ttl = $ttl;
|
||||||
|
$srss->image = $image;
|
||||||
|
$srss->rating = $rating;
|
||||||
|
$srss->textInput = $textInput;
|
||||||
|
$srss->skipDays = $skipDays;
|
||||||
|
$srss->skipHours = $skipHours;
|
||||||
|
|
||||||
|
$item_title = 'item title';
|
||||||
|
$item_link = 'https://example.com';
|
||||||
|
$item_description = 'item <strong>description</strong>';
|
||||||
|
$item_author = 'shikiryu@shikiryu.com';
|
||||||
|
$item_category = new \Shikiryu\SRSS\Entity\Item\Category();
|
||||||
|
$item_category->domain = 'https://shikiryu.com';
|
||||||
|
$item_category->value = 'category shikiryu';
|
||||||
|
$item_comments = $link.'/comments';
|
||||||
|
$item_enclosure = new Enclosure();
|
||||||
|
$item_enclosure->url = $item_link;
|
||||||
|
$item_enclosure->length = 5023;
|
||||||
|
$item_enclosure->type = 'audio/mp3';
|
||||||
|
$item_guid = '123456';
|
||||||
|
$item_pubdate = $pubDate;
|
||||||
|
$item_source = new Source();
|
||||||
|
$item_source->url = $item_link;
|
||||||
|
$item_source->value = 'source';
|
||||||
|
$item_media = new Shikiryu\SRSS\Entity\Media\Content();
|
||||||
|
$item_media->url = $item_link;
|
||||||
|
$item_media->type = 'image/jpg';
|
||||||
|
$item = new Shikiryu\SRSS\Entity\Item();
|
||||||
|
$item->title = $item_title;
|
||||||
|
$item->link = $item_link;
|
||||||
|
$item->description = $item_description;
|
||||||
|
$item->author = $item_author;
|
||||||
|
$item->category[] = $item_category;
|
||||||
|
$item->comments = $item_comments;
|
||||||
|
$item->enclosure = $item_enclosure;
|
||||||
|
$item->guid = $item_guid;
|
||||||
|
$item->pubDate = $item_pubdate;
|
||||||
|
$item->source = $item_source;
|
||||||
|
$item->medias[] = $item_media;
|
||||||
|
|
||||||
|
$srss->addItem($item);
|
||||||
|
|
||||||
|
self::assertTrue($srss->isValid(), var_export($srss->channel->validated + array_map(static fn ($item) => $item->validated, $srss->items), true));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user