Browse Source

Tests for Media RSS

master
J. King 4 years ago
parent
commit
cdad2268e9
  1. 5
      lib/Enclosure/Enclosure.php
  2. 4
      lib/Parser/XML/Construct.php
  3. 39
      lib/Parser/XML/Entry.php
  4. 85
      tests/cases/XML/entry-other.yaml

5
lib/Enclosure/Enclosure.php

@ -10,6 +10,7 @@ namespace MensBeam\Lax\Enclosure;
* @property \MensBeam\Lax\Url $url
* @property \MensBeam\Lax\Text $title
* @property string $type
* @property bool $sample
* @property int $height
* @property int $width
* @property int $duration
@ -19,9 +20,11 @@ namespace MensBeam\Lax\Enclosure;
class Enclosure implements \IteratorAggregate, \ArrayAccess, \Countable {
public $preferred;
protected $data = [];
private $url;
private $type;
private $title;
private $type;
private $sample;
private $height;
private $width;
private $duration;

4
lib/Parser/XML/Construct.php

@ -200,9 +200,9 @@ abstract class Construct {
$custom = false;
$rel = trim($rel);
if ($rel === "") {
$rel = "alternate";
$rel = "alternate"; // @codeCoverageIgnore
} elseif (strpos(strtolower($rel), "http://www.iana.org/assignments/relation/") === 0) {
$rel = substr($rel, 41);
$rel = substr($rel, 41); // @codeCoverageIgnore
} elseif (preg_match("<^[a-z\.\-]+$>i", $rel)) {
$rel = strtolower($rel);
} else {

39
lib/Parser/XML/Entry.php

@ -24,6 +24,10 @@ class Entry extends Construct implements \MensBeam\Lax\Parser\Entry {
'duration' => "@duration",
'bitrate' => "@bitrate"
];
protected const ENCLOSURE_ATTR_BOOLEANS = [
'preferred' => "@isDefault[normalize-space()='true']",
'sample' => "@expression[normalize-space()='sample']",
];
public function __construct(\DOMElement $data, XPath $xpath, FeedStruct $feed) {
$this->subject = $data;
@ -238,16 +242,19 @@ class Entry extends Construct implements \MensBeam\Lax\Parser\Entry {
$groupTitle = $this->fetchTitleMediaRss($node) ?? $entryTitle;
$group = new Enclosure;
foreach ($this->xpath->query("media:content", $node) as $subNode) {
if ($enc = $this->parseMediaRssEnclosure($subNode, true)) {
if ($enc = $this->parseMediaRssEnclosure($subNode)) {
$enc->title = $enc->title ?? $groupTitle;
$group[] = $enc;
}
}
if (sizeof($group)) {
if ($this->fetchString("@isDefault", "(?-i:true)", false, $node)) {
$group->preferred = true;
}
$out[] = $group;
}
} else {
if ($enc = $this->parseMediaRssEnclosure($node, false)) {
if ($enc = $this->parseMediaRssEnclosure($node)) {
$enc->title = $enc->title ?? $entryTitle;
$out[] = $enc;
}
@ -289,18 +296,26 @@ class Entry extends Construct implements \MensBeam\Lax\Parser\Entry {
return sizeof($out) ? $out : null;
}
protected function parseMediaRssEnclosure(\DOMElement $node, bool $group): ?Enclosure {
protected function parseMediaRssEnclosure(\DOMElement $node): ?Enclosure {
assert($node->localName === "content" && $node->namespaceURI === XPath::NS['media']);
$out = new Enclosure;
$out->url = $this->fetchUrl("@url", $node);
$out->type = $this->parseMediaType($this->fetchString("@type", ".+", false, $node)) ?? $this->fetchString("@medium", "image|audio|video|document|executable", false, $node);
$out->title = $this->fetchTitleMediaRss($node);
foreach (self::ENCLOSURE_ATTR_INTEGERS as $prop => $query) {
$value = (int) $this->fetchString($query, "\d+", false, $node);
$out->$prop = $value ?: null;
$url = $this->fetchUrl("@url", $node);
if ($url) {
$out = new Enclosure;
$out->url = $url;
$out->type = $this->parseMediaType($this->fetchString("@type", ".+", false, $node) ?? "", $url) ?? $this->fetchString("@medium", "(?-i:image|audio|video|document|executable)", false, $node);
$out->title = $this->fetchTitleMediaRss($node);
foreach (self::ENCLOSURE_ATTR_INTEGERS as $prop => $query) {
$value = (int) $this->fetchString($query, "\d+", false, $node);
$out->$prop = $value ?: null;
}
foreach (self::ENCLOSURE_ATTR_BOOLEANS as $prop => $query) {
if (!is_null($this->fetchString($query, null, false, $node))) {
$out->$prop = true;
}
}
return $out;
}
return $out->url ? $out : null;
return null;
}
protected function fetchTitleMediaRss(\DOMElement $context): ?Text {

85
tests/cases/XML/entry-other.yaml

@ -146,3 +146,88 @@ Google Play categories:
- categories:
- name: Arts
- name: Music
Media RSS enclosures:
input: >
<rss><channel xmlns:media="http://search.yahoo.com/mrss/">
<item>
<media:content url="http://[/"/>
<media:content url="http://example.com/"/>
<media:content url="http://example.com/" type="image/svg+xml"/>
<media:content url="http://example.com/" medium="image"/>
<media:content url="http://example.com/entry.m4a" medium="image"/>
</item>
<item>
<media:content url="http://example.com/">
<media:title>Plain title</media:title>
</media:content>
<media:content url="http://example.com/">
<media:title type=" html ">HTML title</media:title>
</media:content>
<media:content url="http://example.com/">
<media:title type="HTML">Plain title</media:title>
</media:content>
</item>
<item>
<media:content url="http://example.com/" isDefault="true" expression="sample"/>
<media:content url="http://example.com/" fileSize="002567" duration="000000001" width="bogus" height="-20" bitrate="0"/>
<media:content url="http://example.com/" fileSize="1.0" duration="2e6" width="800" height="0600" bitrate="500"/>
</item>
<item>
<media:title>Entry title</media:title>
<media:content url="http://example.com/"/>
<media:group>
<media:title>Group title</media:title>
<media:content url="http://example.com/" isDefault="true"/>
<media:content url="http://example.com/">
<media:title>Enclosure title</media:title>
</media:content>
</media:group>
<media:group isDefault="true">
<media:content url="http://example.com/"/>
</media:group>
<media:group isDefault="true">
<media:content url="http://[/"/>
</media:group>
</item>
</channel></rss>
output:
format: rss
entries:
- enclosures:
- url: 'http://example.com/'
- url: 'http://example.com/'
type: 'image/svg+xml'
- url: 'http://example.com/'
type: 'image'
- url: 'http://example.com/entry.m4a'
type: 'audio/mp4'
- enclosures:
- url: 'http://example.com/'
title: 'Plain title'
- url: 'http://example.com/'
title: {html: 'HTML title'}
- url: 'http://example.com/'
title: 'Plain title'
- enclosures:
- url: 'http://example.com/'
preferred: true
sample: true
- url: 'http://example.com/'
size: 2567
duration: 1
- url: 'http://example.com/'
width: 800
height: 600
bitrate: 500
- enclosures:
- url: 'http://example.com/'
title: 'Entry title'
- data:
- url: 'http://example.com/'
title: 'Group title'
preferred: true
- url: 'http://example.com/'
title: 'Enclosure title'
- data: [{url: 'http://example.com/', title: 'Entry title'}]
preferred: true

Loading…
Cancel
Save