From bc0e818bbced742610247c9d3a47ab5999500bbb Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Thu, 6 Apr 2023 11:07:06 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactores=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For #4 --- composer.json | 3 +- src/Entity/Channel.php | 18 +- src/Entity/Item.php | 17 +- src/Entity/Media/Content.php | 1 - src/Entity/SRSSElement.php | 16 ++ src/SRSS.php | 380 +++++------------------------------ src/SRSSBuilder.php | 158 ++++++++++++++- src/SRSSItem.php | 4 +- src/SRSSParser.php | 146 ++++++++++++++ tests/BasicReader.php | 19 ++ tests/MediaTest.php | 13 +- 11 files changed, 438 insertions(+), 337 deletions(-) create mode 100644 src/Entity/SRSSElement.php create mode 100644 src/SRSSParser.php diff --git a/composer.json b/composer.json index c49cd62..48d4820 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "phpunit/phpunit": "^9" }, "require": { - "ext-dom": "*" + "ext-dom": "*", + "ext-libxml": "*" } } diff --git a/src/Entity/Channel.php b/src/Entity/Channel.php index 176237e..c0bae45 100644 --- a/src/Entity/Channel.php +++ b/src/Entity/Channel.php @@ -4,7 +4,7 @@ namespace Shikiryu\SRSS\Entity; use Shikiryu\SRSS\Entity\Channel\Image; -class Channel +class Channel implements SRSSElement { public string $title; public string $link; @@ -28,4 +28,20 @@ class Channel public ?string $skipDays; public array $required = ['title', 'link', 'description']; + + /** + * @return bool + */ + public function isValid(): bool + { + return count(array_filter($this->required, fn($field) => !empty($this->{$field}))) === 0; + } + + /** + * @return array + */ + public function toArray(): array + { + return get_object_vars($this); + } } \ No newline at end of file diff --git a/src/Entity/Item.php b/src/Entity/Item.php index a39ecc4..e3cd66b 100644 --- a/src/Entity/Item.php +++ b/src/Entity/Item.php @@ -2,7 +2,7 @@ namespace Shikiryu\SRSS\Entity; -class Item +class Item implements SRSSElement { public ?string $title; public ?string $link; @@ -15,5 +15,20 @@ class Item public ?string $pubDate; public ?string $source; + /** + * @var \Shikiryu\SRSS\Entity\Media\Content[] + */ + public array $medias = []; + public array $required = ['description']; + + public function isValid(): bool + { + return count(array_filter($this->required, fn($field) => !empty($this->{$field}))) === 0; + } + + public function toArray(): array + { + return get_object_vars($this); + } } \ No newline at end of file diff --git a/src/Entity/Media/Content.php b/src/Entity/Media/Content.php index 05a045f..1e09671 100644 --- a/src/Entity/Media/Content.php +++ b/src/Entity/Media/Content.php @@ -58,7 +58,6 @@ class Content extends DomDocument } } - /** * main getter for properties * diff --git a/src/Entity/SRSSElement.php b/src/Entity/SRSSElement.php new file mode 100644 index 0000000..607d3b3 --- /dev/null +++ b/src/Entity/SRSSElement.php @@ -0,0 +1,16 @@ + 'nohtml', - 'link' => 'link', - 'description' => 'html', - 'language' => '', + 'title' => 'nohtml', + 'link' => 'link', + 'description' => 'html', + 'language' => '', //'language' => 'lang', - 'copyright' => 'nohtml', - 'pubDate' => 'date', - 'lastBuildDate' => 'date', - 'category' => 'nohtml', - 'docs' => 'link', - 'cloud' => '', - 'generator' => 'nohtml', - 'managingEditor' => 'email', - 'webMaster' => 'email', - 'ttl' => 'int', - 'image' => '', - 'rating' => 'nohtml', + 'copyright' => 'nohtml', + 'pubDate' => 'date', + 'lastBuildDate' => 'date', + 'category' => 'nohtml', + 'docs' => 'link', + 'cloud' => '', + 'generator' => 'nohtml', + 'managingEditor' => 'email', + 'webMaster' => 'email', + 'ttl' => 'int', + 'image' => '', + 'rating' => 'nohtml', //'textInput' => '', - 'skipHours' => 'hour', - 'skipDays' => 'day', + 'skipHours' => 'hour', + 'skipDays' => 'day', ]; /** @@ -49,49 +43,20 @@ class SRSS extends DomDocument implements Iterator */ public function __construct() { - libxml_use_internal_errors(true); - parent::__construct(); - $this->xpath = new DOMXpath($this); $this->attr = []; $this->items = []; $this->position = 0; - $this->formatOutput = true; - $this->preserveWhiteSpace = false; - } - - /** - * Destructor - * manage of libxml errors - */ - public function __destruct() - { - foreach (libxml_get_errors() as $error) { - error_log($error->message, 3, 'error.log'); - } - libxml_clear_errors(); } /** * @param string $link url of the rss - * @throws SRSSException + * * @return SRSS + * @throws SRSSException */ public static function read(string $link): SRSS { - $doc = new SRSS; - if(@$doc->load($link)) { // We don't want the warning in case of bad XML. Let's manage it with an exception. - $channel = $doc->getElementsByTagName('channel'); - if($channel->length == 1){ // Good URL and good RSS - $doc->_loadAttributes(); // loading channel properties - $doc->getItems(); // loading all items - - return $doc; - } - - throw new SRSSException('invalid file '.$link); - } - - throw new SRSSException('Can not open file '.$link); + return (new SRSSParser())->parse($link); } /** @@ -101,145 +66,13 @@ class SRSS extends DomDocument implements Iterator public static function create() { $doc = new SRSS; - $root = $doc->createElement('rss'); - $root->setAttribute('version', '2.0'); - $channel = $doc->createElement('channel'); - $root->appendChild($channel); - $doc->appendChild($root); - $doc->encoding = "UTF-8"; - $doc->generator = 'Shikiryu RSS'; - // $docs = 'http://www.scriptol.fr/rss/RSS-2.0.html'; + $doc->channel = new Channel(); $doc->items = []; return $doc; } - /** - * getter of "image"'s channel attributes - * @return string|array - * TODO - */ - public function image() - { - $args = func_get_args(); - if (func_num_args() == 0) { - $args[0] = 'url'; - } - $img = $this->xpath->query('//channel/image'); - if($img->length != 1) { // is not in channel - return null; - } - $img = $img->item(0); - $r = []; - foreach($img->childNodes as $child) { - if($child->nodeType == XML_ELEMENT_NODE && in_array($child->nodeName, $args)) { - $r[$child->nodeName] = $child->nodeValue; - } - } - return (func_num_args() > 1) ? $r : $r[$args[0]]; - } - - /** - * setter of "image"'s channel attributes - * @param $url string picture's url - * @param $title string picture's title - * @param $link string link on the picture - * @param $width int width - * @param $height int height - * @param $description string description - * TODO - */ - public function setImage($url, $title, $link, $width = 0, $height = 0, $description = '') - { - $channel = $this->_getChannel(); - $array = []; - $url = SRSSTools::checkLink($url); - $array['url'] = $url; - $title = SRSSTools::noHTML($title); - $array['title'] = $title; - $link = SRSSTools::checkLink($link); - $array['link'] = $link; - if($width != 0) - { - $width = SRSSTools::checkInt($width); - $array['width'] = $width; - } - if($height != 0) - { - $height = SRSSTools::checkInt($height); - $array['height'] = $height; - } - if($description != 0) - { - $description = SRSSTools::noHTML($description); - $array['description'] = $description; - } - if($this->image == null) - { - $node = $this->createElement('image'); - $urlNode = $this->createElement('url', $url); - $titleNode = $this->createElement('title', $title); - $linkNode = $this->createElement('link', $link); - $node->appendChild($urlNode); - $node->appendChild($titleNode); - $node->appendChild($linkNode); - if($width != 0) - { - $widthNode = $this->createElement('width', $width); - $node->appendChild($widthNode); - } - if($height != 0) - { - $heightNode = $this->createElement('height', $height); - $node->appendChild($heightNode); - } - if($description != '') - { - $descNode = $this->createElement('description', $description); - $node->appendChild($descNode); - } - $channel->appendChild($node); - } - $this->attr['image'] = $array; - } - - /** - * setter of "cloud"'s channel attributes - * @param $domain string domain - * @param $port int port - * @param $path string path - * @param $registerProcedure string register procedure - * @param $protocol string protocol - * TODO - */ - public function setCloud($domain, $port, $path, $registerProcedure, $protocol) - { - $channel = $this->_getChannel(); - $array = array(); - $domain = SRSSTools::noHTML($domain); - $array['domain'] = $domain; - $port = SRSSTools::checkInt($port); - $array['port'] = $port; - $path = SRSSTools::noHTML($path); - $array['path'] = $path; - $registerProcedure = SRSSTools::noHTML($registerProcedure); - $array['registerProcedure'] = $registerProcedure; - $protocol = SRSSTools::noHTML($protocol); - $array['protocol'] = $protocol; - if($this->cloud == null) - { - $node = $this->createElement('cloud'); - $node->setAttribute('domain', $domain); - $node->setAttribute('port', $port); - $node->setAttribute('path', $path); - $node->setAttribute('registerProcedure', $registerProcedure); - $node->setAttribute('protocol', $protocol); - $channel->appendChild($node); - } - $this->attr['cloud'] = $array; - } - /** * check if current RSS is a valid one (based on specifications) * @return bool @@ -251,29 +84,15 @@ class SRSS extends DomDocument implements Iterator $items = $this->getItems(); $invalidItems = []; $i = 1; - foreach($items as $item){ - if($item->isValid() === false){ + foreach ($items as $item) { + if ($item->isValid() === false) { $invalidItems[] = $i; $valid = false; } $i++; } - return ($valid && $this->title != null && $this->link != null && $this->description != null); - } - /** - * getter of current RSS channel - * @return \DOMNode - * @throws SRSSException - */ - private function _getChannel(): \DOMNode - { - $channel = $this->getElementsByTagName('channel'); - if($channel->length != 1) { - throw new SRSSException('channel node not created, or too many channel nodes'); - } - - return $channel->item(0); + return ($valid && $this->channel->isValid()); } /** @@ -283,104 +102,61 @@ class SRSS extends DomDocument implements Iterator */ public function __isset($name) { - return isset($this->attr[$name]); + return isset($this->channel->{$name}); } /** * setter of others attributes + * * @param $name * @param $val + * * @throws SRSSException */ public function __set($name, $val) { - $channel = $this->_getChannel(); - if(array_key_exists($name, $this->possibleAttr)){ - $flag = $this->possibleAttr[$name]; - $val = SRSSTools::check($val, $flag); - if(!empty($val)){ - if($this->$name == null){ - $node = $this->createElement($name, $val); - $channel->appendChild($node); - } - $this->attr[$name] = $val; - } - }else{ - throw new SRSSException($name.' is not a possible item'); + if (!array_key_exists($name, $this->possibleAttr)) { + throw new SRSSException($name . ' is not a possible item'); + } + $flag = $this->possibleAttr[$name]; + $val = SRSSTools::check($val, $flag); + if (!empty($val)) { + $this->channel->{$name} = $val; } } /** * getter of others attributes + * * @param $name + * * @return null|string - * @throws SRSSException */ public function __get($name) { - if (isset($this->channel->{$name})) { - return $this->channel->{$name}; - } -// $channel = $this->_getChannel(); - if(array_key_exists($name, $this->possibleAttr)){ - $tmp = $this->xpath->query('//channel/'.$name); - if($tmp->length != 1) { - return null; - } - return $tmp->item(0)->nodeValue; - } - - throw new SRSSException($name.' is not a possible value.'); - } - - /** - * add a SRSS Item as an item into current RSS as first item - * @param SRSSItem $item - */ - public function addItemBefore(SRSSItem $item) - { - $node = $this->importNode($item->getItem(), true); - $items = $this->getElementsByTagName('item'); - if($items->length != 0){ - $firstNode = $items->item(0); - if($firstNode != null) - $firstNode->parentNode->insertBefore($node, $firstNode); - else - $this->addItem($item); - } - else - $this->addItem($item); - } - - /** - * add a SRSS Item as an item into current RSS - * @param SRSSItem $item - */ - public function addItem(SRSSItem $item) - { - $node = $this->importNode($item->getItem(), true); - $channel = $this->_getChannel(); - $channel->appendChild($node); + return $this->channel->{$name} ?? null; } /** * rewind from Iterator */ - public function rewind() { + public function rewind(): void + { $this->position = 0; } /** * current from Iterator */ - public function current() { + public function current() + { return $this->items[$this->position]; } /** * key from Iterator */ - #[ReturnTypeWillChange] public function key(): int + public function key(): int { return $this->position; } @@ -388,7 +164,7 @@ class SRSS extends DomDocument implements Iterator /** * next from Iterator */ - #[ReturnTypeWillChange] public function next(): void + public function next(): void { ++$this->position; } @@ -396,7 +172,7 @@ class SRSS extends DomDocument implements Iterator /** * valid from Iterator */ - #[ReturnTypeWillChange] public function valid(): bool + public function valid(): bool { return isset($this->items[$this->position]); } @@ -417,11 +193,13 @@ class SRSS extends DomDocument implements Iterator public function getLast(): Item { $items = $this->getItems(); + return $items[array_key_last($items)]; } /** * getter of an item + * * @param $i int * * @return Item|null @@ -429,6 +207,7 @@ class SRSS extends DomDocument implements Iterator public function getItem(int $i): ?Item { $i--; + return $this->items[$i] ?? null; } @@ -439,62 +218,9 @@ class SRSS extends DomDocument implements Iterator */ public function getItems(): array { - if (!empty($this->items)) { - return $this->items; - } - - $channel = $this->_getChannel(); - /** @var DOMNodeList $items */ - $items = $channel->getElementsByTagName('item'); - $length = $items->length; - $this->items = []; - if ($length > 0) { - for($i = 0; $i < $length; $i++) { - $this->items[$i] = SRSSItem::read($items->item($i)); - } - } - return $this->items; } - /** - * display XML - * see DomDocument's docs - */ - public function show(): bool|string - { - // TODO build - return $this->saveXml(); - } - - - /** - * putting all RSS attributes into the object - * @throws SRSSException - */ - private function _loadAttributes(): void - { - $node_channel = $this->_getChannel(); - $this->channel = new Channel(); - - foreach($node_channel->childNodes as $child) { - if($child->nodeType == XML_ELEMENT_NODE && $child->nodeName !== 'item') { - if($child->nodeName == 'image') { - $image = new Image(); - foreach($child->childNodes as $children) { - if($children->nodeType == XML_ELEMENT_NODE) { - $image->{$child->nodeName} = $children->nodeValue; - } - } - $this->channel->image = $image; - - } else { - $this->channel->{$child->nodeName} = $child->nodeValue; - } - } - } - } - /** * transform current object into an array * @return array @@ -504,10 +230,10 @@ class SRSS extends DomDocument implements Iterator { $doc = $this->channel->toArray(); - foreach($this->getItems() as $item) { + foreach ($this->getItems() as $item) { $doc['items'][] = $item->toArray(); } return $doc; } -} \ No newline at end of file +} diff --git a/src/SRSSBuilder.php b/src/SRSSBuilder.php index 6612563..9d89403 100644 --- a/src/SRSSBuilder.php +++ b/src/SRSSBuilder.php @@ -2,7 +2,161 @@ namespace Shikiryu\SRSS; -class SRSSBuilder -{ +use DOMDocument; +class SRSSBuilder extends DomDocument +{ + public function build() + { + $root = $this->createElement('rss'); + $root->setAttribute('version', '2.0'); + $channel = $this->createElement('channel'); + $root->appendChild($channel); + $this->appendChild($root); + $this->encoding = 'UTF-8'; + $this->generator = 'Shikiryu RSS'; + $this->formatOutput = true; + $this->preserveWhiteSpace = false; + // $docs = 'http://www.scriptol.fr/rss/RSS-2.0.html'; + } + + /** + * add a SRSS Item as an item into current RSS as first item + * @param SRSSItem $item + */ + public function addItemBefore(SRSSItem $item) + { + $node = $this->importNode($item->getItem(), true); + $items = $this->getElementsByTagName('item'); + if($items->length != 0){ + $firstNode = $items->item(0); + if($firstNode != null) + $firstNode->parentNode->insertBefore($node, $firstNode); + else + $this->addItem($item); + } + else + $this->addItem($item); + } + + /** + * add a SRSS Item as an item into current RSS + * @param SRSSItem $item + */ + public function addItem(SRSSItem $item) + { + $node = $this->importNode($item->getItem(), true); + $channel = $this->_getChannel(); + $channel->appendChild($node); + } + + /** + * display XML + * see DomDocument's docs + */ + public function show(): bool|string + { + // TODO build + return $this->saveXml(); + } + + /** + * setter of "image"'s channel attributes + * @param $url string picture's url + * @param $title string picture's title + * @param $link string link on the picture + * @param $width int width + * @param $height int height + * @param $description string description + * TODO + */ + public function setImage($url, $title, $link, $width = 0, $height = 0, $description = '') + { + $channel = $this->_getChannel(); + $array = []; + $url = SRSSTools::checkLink($url); + $array['url'] = $url; + $title = SRSSTools::noHTML($title); + $array['title'] = $title; + $link = SRSSTools::checkLink($link); + $array['link'] = $link; + if($width != 0) + { + $width = SRSSTools::checkInt($width); + $array['width'] = $width; + } + if($height != 0) + { + $height = SRSSTools::checkInt($height); + $array['height'] = $height; + } + if($description != 0) + { + $description = SRSSTools::noHTML($description); + $array['description'] = $description; + } + if($this->image == null) + { + $node = $this->createElement('image'); + $urlNode = $this->createElement('url', $url); + $titleNode = $this->createElement('title', $title); + $linkNode = $this->createElement('link', $link); + $node->appendChild($urlNode); + $node->appendChild($titleNode); + $node->appendChild($linkNode); + if($width != 0) + { + $widthNode = $this->createElement('width', $width); + $node->appendChild($widthNode); + } + if($height != 0) + { + $heightNode = $this->createElement('height', $height); + $node->appendChild($heightNode); + } + if($description != '') + { + $descNode = $this->createElement('description', $description); + $node->appendChild($descNode); + } + $channel->appendChild($node); + } + $this->attr['image'] = $array; + } + + /** + * setter of "cloud"'s channel attributes + * @param $domain string domain + * @param $port int port + * @param $path string path + * @param $registerProcedure string register procedure + * @param $protocol string protocol + * TODO + */ + public function setCloud($domain, $port, $path, $registerProcedure, $protocol) + { + $channel = $this->_getChannel(); + $array = array(); + $domain = SRSSTools::noHTML($domain); + $array['domain'] = $domain; + $port = SRSSTools::checkInt($port); + $array['port'] = $port; + $path = SRSSTools::noHTML($path); + $array['path'] = $path; + $registerProcedure = SRSSTools::noHTML($registerProcedure); + $array['registerProcedure'] = $registerProcedure; + $protocol = SRSSTools::noHTML($protocol); + $array['protocol'] = $protocol; + if($this->cloud == null) + { + $node = $this->createElement('cloud'); + $node->setAttribute('domain', $domain); + $node->setAttribute('port', $port); + $node->setAttribute('path', $path); + $node->setAttribute('registerProcedure', $registerProcedure); + $node->setAttribute('protocol', $protocol); + $channel->appendChild($node); + } + $this->attr['cloud'] = $array; + } } \ No newline at end of file diff --git a/src/SRSSItem.php b/src/SRSSItem.php index e940e19..4c52bd5 100644 --- a/src/SRSSItem.php +++ b/src/SRSSItem.php @@ -59,10 +59,8 @@ class SRSSItem extends DomDocument if ($child->nodeType === XML_ELEMENT_NODE && $child->nodeName !== 'item') { if (array_key_exists($child->nodeName, self::$possibilities) && self::$possibilities[$child->nodeName] === 'folder') { self::_loadChildAttributes($item, $child); - } elseif ($child->nodeName === 'media:group') { - // TODO } elseif ($child->nodeName === 'media:content') { - $item->{$child->nodeName} = new Content($child); + $item->medias[] = new Content($child); } else { $item->{$child->nodeName} = $child->nodeValue; } diff --git a/src/SRSSParser.php b/src/SRSSParser.php new file mode 100644 index 0000000..7aa83e3 --- /dev/null +++ b/src/SRSSParser.php @@ -0,0 +1,146 @@ +xpath = new DOMXpath($this); + $this->doc = new SRSS(); + } + + /** + * Destructor + * manage of libxml errors + */ + public function __destruct() + { + foreach (libxml_get_errors() as $error) { + error_log($error->message, 3, 'error.log'); + } + libxml_clear_errors(); + } + + /** + * @param string $link + * + * @return \Shikiryu\SRSS\SRSS + * @throws \Shikiryu\SRSS\SRSSException + */ + public function parse(string $link) + { + if(@$this->load($link)) { // We don't want the warning in case of bad XML. Let's manage it with an exception. + $channel = $this->getElementsByTagName('channel'); + if($channel->length === 1){ // Good URL and good RSS + $this->_loadAttributes(); // loading channel properties + $this->getItems(); // loading all items + + return $this->doc; + } + + throw new SRSSException('invalid file '.$link); + } + + throw new SRSSException('Can not open file '.$link); + } + + /** + * @return array|mixed + * @throws \Shikiryu\SRSS\SRSSException + */ + private function getItems() + { + $channel = $this->_getChannel(); + /** @var DOMNodeList $items */ + $items = $channel->getElementsByTagName('item'); + $length = $items->length; + $this->doc->items = []; + if ($length > 0) { + for($i = 0; $i < $length; $i++) { + $this->doc->items[$i] = SRSSItem::read($items->item($i)); + } + } + + return $this->doc->items; + } + /** + * putting all RSS attributes into the object + * @throws SRSSException + */ + private function _loadAttributes(): void + { + $node_channel = $this->_getChannel(); + $this->doc->channel = new Channel(); + + foreach($node_channel->childNodes as $child) { + if ($child->nodeType === XML_ELEMENT_NODE && $child->nodeName !== 'item') { + if($child->nodeName === 'image') { + $image = new Image(); + foreach($child->childNodes as $children) { + if($children->nodeType == XML_ELEMENT_NODE) { + $image->{$child->nodeName} = $children->nodeValue; + } + } + $this->doc->channel->image = $image; + + } else { + $this->doc->channel->{$child->nodeName} = $child->nodeValue; + } + } + } + } + + + /** + * getter of current RSS channel + * @return \DOMNode + * @throws SRSSException + */ + private function _getChannel(): \DOMNode + { + $channel = $this->getElementsByTagName('channel'); + if($channel->length != 1) { + throw new SRSSException('channel node not created, or too many channel nodes'); + } + + return $channel->item(0); + } + + /** + * getter of "image"'s channel attributes + * @return string|array + * TODO + */ + public function image() + { + $args = func_get_args(); + if (func_num_args() == 0) { + $args[0] = 'url'; + } + $img = $this->xpath->query('//channel/image'); + if ($img->length != 1) { // is not in channel + return null; + } + $img = $img->item(0); + $r = []; + foreach ($img->childNodes as $child) { + if ($child->nodeType == XML_ELEMENT_NODE && in_array($child->nodeName, $args)) { + $r[$child->nodeName] = $child->nodeValue; + } + } + + return (func_num_args() > 1) ? $r : $r[$args[0]]; + } +} \ No newline at end of file diff --git a/tests/BasicReader.php b/tests/BasicReader.php index 400eabb..1ce19a4 100644 --- a/tests/BasicReader.php +++ b/tests/BasicReader.php @@ -20,4 +20,23 @@ class BasicReader extends TestCase $this->expectException(SRSSException::class); $rss = SRSS::read('not_found.xml'); } + + public function testSpecificationExampleRSS() + { + $rss = SRSS::read(__DIR__.'/resources/harvard.xml'); + self::assertEquals('Liftoff News', $rss->title); + self::assertEquals('http://liftoff.msfc.nasa.gov/', $rss->link); + self::assertEquals('Liftoff to Space Exploration.', $rss->description); + self::assertEquals('en-us', $rss->language); + self::assertEquals('Tue, 10 Jun 2003 04:00:00 GMT', $rss->pubDate); + self::assertEquals('Tue, 10 Jun 2003 09:41:01 GMT', $rss->lastBuildDate); + self::assertEquals('http://blogs.law.harvard.edu/tech/rss', $rss->docs); + self::assertEquals('Weblog Editor 2.0', $rss->generator); + self::assertEquals('editor@example.com', $rss->managingEditor); + self::assertEquals('webmaster@example.com', $rss->webMaster); + self::assertCount(4, $rss->items); + self::assertEquals('Star City', $rss->getFirst()->title); + self::assertEquals('http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp', $rss->getLast()->link); + self::assertEquals('Fri, 30 May 2003 11:06:42 GMT', $rss->getItem(2)->pubDate); + } } \ No newline at end of file diff --git a/tests/MediaTest.php b/tests/MediaTest.php index 655f04f..ae1e96a 100644 --- a/tests/MediaTest.php +++ b/tests/MediaTest.php @@ -13,6 +13,17 @@ class MediaTest extends TestCase $first_item = $rss->getFirst(); self::assertEquals('Kirstie Alley, \'Cheers\' and \'Veronica\'s Closet\' star, dead at 71', $first_item->title); - self::assertEquals('https://cdn.cnn.com/cnnnext/dam/assets/221205172141-kirstie-alley-2005-super-169.jpg', $first_item->{'media:content'}->url); + self::assertEquals('https://cdn.cnn.com/cnnnext/dam/assets/221205172141-kirstie-alley-2005-super-169.jpg', $first_item->medias[0]->url); + } + + public function testMusicVideo() + { + $rss = SRSS::read('resources/media/music-video.xml'); + self::assertEquals('Music Videos 101', $rss->title); + + self::assertCount(1, $rss->items); + + $first_item = $rss->getFirst(); + self::assertEquals('http://www.foo.com/movie.mov', $first_item->medias[0]->url); } } \ No newline at end of file