Browse Source

Implement and test Atom enclosures

master
J. King 4 years ago
parent
commit
35a9a5af78
  1. 32
      lib/Parser/XML/Entry.php
  2. 27
      lib/Parser/XML/XPath.php
  3. 2
      tests/cases/AbstractParserTestCase.php
  4. 23
      tests/cases/XML/entry-atom.yaml

32
lib/Parser/XML/Entry.php

@ -11,6 +11,7 @@ use MensBeam\Lax\Entry as EntryStruct;
use MensBeam\Lax\Person\Collection as PersonCollection;
use MensBeam\Lax\Category\Collection as CategoryCollection;
use MensBeam\Lax\Enclosure\Collection as EnclosureCollection;
use MensBeam\Lax\Enclosure\Enclosure;
use MensBeam\Lax\Date;
use MensBeam\Lax\Text;
use MensBeam\Lax\Url;
@ -154,7 +155,11 @@ class Entry extends Construct implements \MensBeam\Lax\Parser\Entry {
}
public function getEnclosures(): EnclosureCollection {
return new EnclosureCollection;
return $this->getEnclosuresMediaRss()
?? $this->getEnclosuresAtom()
?? $this->getEnclosuresRss1()
?? $this->getEnclosuresRss2()
?? new EnclosureCollection;
}
protected function getRelatedLinkDefinitive(): ?url {
@ -202,4 +207,29 @@ class Entry extends Construct implements \MensBeam\Lax\Parser\Entry {
return $this->fetchAtomPeople("atom:contributor", "contributor", $context) // Atom contributors
?? $this->fetchPeople("dc:contributor|dct:contributor", "contributor", $context); // Dublin Core contributors
}
protected function getEnclosuresAtom(): ?EnclosureCollection {
$out = new EnclosureCollection;
foreach ($this->fetchAtomRelations("enclosure") as $el) {
$enc = new Enclosure;
$enc->url = $this->fetchUrl("@href", $el);
$enc->type = $this->parseMediaType($el->getAttribute("type"), $enc->url);
$enc->title = $this->fetchString("@title", ".+", false, $el);
$enc->size = ((int) $this->fetchString("@length", "\d+", false, $el)) ?: null;
$out[] = $enc;
}
return sizeof($out) ? $out : null;
}
protected function getEnclosuresMediaRss(): ?EnclosureCollection {
return null;
}
protected function getEnclosuresRss1(): ?EnclosureCollection {
return null;
}
protected function getEnclosuresRss2(): ?EnclosureCollection {
return null;
}
}

27
lib/Parser/XML/XPath.php

@ -8,19 +8,20 @@ namespace MensBeam\Lax\Parser\XML;
class XPath extends \DOMXpath {
public const NS = [
'atom' => "http://www.w3.org/2005/Atom", // Atom syndication format https://tools.ietf.org/html/rfc4287
'rss2' => "", // RSS 2.0 does not have a namespace // Really Simple Syndication 2.0.11 http://www.rssboard.org/rss-specification
'rss1' => "http://purl.org/rss/1.0/", // RDF site summary 1.0 http://purl.org/rss/1.0/spec
'rss0' => "http://channel.netscape.com/rdf/simple/0.9/", // RDF Site Summary 0.90 http://www.rssboard.org/rss-0-9-0
'dc' => "http://purl.org/dc/elements/1.1/", // Dublin Core metadata http://purl.org/rss/1.0/modules/dc/
'dct' => "http://purl.org/dc/terms/", // Dublin Core terms https://web.archive.org/web/20071222055924/http://web.resource.org/rss/1.0/modules/dcterms/
'sched' => "http://purl.org/rss/1.0/modules/syndication/", // Syndication schedule extension http://purl.org/rss/1.0/modules/syndication/
'enc' => "http://purl.org/rss/1.0/modules/content/", // Explicitly encoded content extension http://purl.org/rss/1.0/modules/content/
'media' => "http://search.yahoo.com/mrss/", // Embedded media extension http://www.rssboard.org/media-rss
'rdf' => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", // Resource Description Framework https://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/
'xhtml' => "http://www.w3.org/1999/xhtml", // XHTML https://html.spec.whatwg.org/
'apple' => "http://www.itunes.com/dtds/podcast-1.0.dtd", // iTunes podcasts https://help.apple.com/itc/podcasts_connect/#/itcb54353390
'gplay' => "http://www.google.com/schemas/play-podcasts/1.0", // Google Play podcasts https://support.google.com/googleplay/podcasts/answer/6260341
'atom' => "http://www.w3.org/2005/Atom", // Atom syndication format https://tools.ietf.org/html/rfc4287
'rss2' => "", // RSS 2.0 does not have a namespace // Really Simple Syndication 2.0.11 http://www.rssboard.org/rss-specification
'rss1' => "http://purl.org/rss/1.0/", // RDF site summary 1.0 http://purl.org/rss/1.0/spec
'rss0' => "http://channel.netscape.com/rdf/simple/0.9/", // RDF Site Summary 0.90 http://www.rssboard.org/rss-0-9-0
'dc' => "http://purl.org/dc/elements/1.1/", // Dublin Core metadata http://purl.org/rss/1.0/modules/dc/
'dct' => "http://purl.org/dc/terms/", // Dublin Core terms https://web.archive.org/web/20071222055924/http://web.resource.org/rss/1.0/modules/dcterms/
'sched' => "http://purl.org/rss/1.0/modules/syndication/", // Syndication schedule extension http://purl.org/rss/1.0/modules/syndication/
'enc' => "http://purl.org/rss/1.0/modules/content/", // Explicitly encoded content extension http://purl.org/rss/1.0/modules/content/
'media' => "http://search.yahoo.com/mrss/", // Embedded media extension http://www.rssboard.org/media-rss
'rss1file' => "http://purl.oclc.org/net/rss_2.0/enc#", // RSS 1.0 enclosures https://foz.home.xs4all.nl/mod_enclosure.html
'rdf' => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", // Resource Description Framework https://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/
'xhtml' => "http://www.w3.org/1999/xhtml", // XHTML https://html.spec.whatwg.org/
'apple' => "http://www.itunes.com/dtds/podcast-1.0.dtd", // iTunes podcasts https://help.apple.com/itc/podcasts_connect/#/itcb54353390
'gplay' => "http://www.google.com/schemas/play-podcasts/1.0", // Google Play podcasts https://support.google.com/googleplay/podcasts/answer/6260341
];
public $rss2 = false;

2
tests/cases/AbstractParserTestCase.php

@ -177,7 +177,7 @@ class AbstractParserTestCase extends \PHPUnit\Framework\TestCase {
private function makeEnclosure(\stdClass $enclosure): Enclosure {
$e = new Enclosure;
foreach ($enclosure as $k => $v) {
if ($k === "urli") {
if ($k === "url") {
$e->$k = $this->makeUrl($v);
} else {
$e->$k = $v;

23
tests/cases/XML/entry-atom.yaml

@ -283,3 +283,26 @@ Categories:
- name: eek
- categories:
- name: ack
Enclosures:
input: >
<feed xmlns="http://www.w3.org/2005/Atom">
<entry>
<link rel="enclosure" href="http://example.com/" type="image/svg+xml" length="2112"/>
<link rel="enclosure" href="http://example.net/" type="image" title=" Plain title"/>
<link rel="enclosure" href="http://example.net/enclosure.png" length="bogus"/>
</entry>
</feed>
output:
format: atom
version: '1.0'
entries:
- enclosures:
- url: 'http://example.com/'
type: 'image/svg+xml'
size: 2112
- url: 'http://example.net/'
type: 'image'
title: 'Plain title'
- url: 'http://example.net/enclosure.png'
type: 'image/png'

Loading…
Cancel
Save