diff options
Diffstat (limited to '3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication')
3 files changed, 524 insertions, 0 deletions
diff --git a/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Atom.php b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Atom.php new file mode 100644 index 000000000..a379056b4 --- /dev/null +++ b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Atom.php @@ -0,0 +1,220 @@ +<?php + +namespace PicoFeed\Syndication; + +use DomDocument; +use DomElement; +use DomAttr; + +/** + * Atom writer class + * + * @author Frederic Guillot + * @package Syndication + */ +class Atom extends Writer +{ + /** + * List of required properties for each feed + * + * @access private + * @var array + */ + private $required_feed_properties = array( + 'title', + 'site_url', + 'feed_url', + ); + + /** + * List of required properties for each item + * + * @access private + * @var array + */ + private $required_item_properties = array( + 'title', + 'url', + ); + + /** + * Get the Atom document + * + * @access public + * @param string $filename Optional filename + * @return string + */ + public function execute($filename = '') + { + $this->checkRequiredProperties($this->required_feed_properties, $this); + + $this->dom = new DomDocument('1.0', 'UTF-8'); + $this->dom->formatOutput = true; + + // <feed/> + $feed = $this->dom->createElement('feed'); + $feed->setAttributeNodeNS(new DomAttr('xmlns', 'http://www.w3.org/2005/Atom')); + + // <generator/> + $generator = $this->dom->createElement('generator', 'PicoFeed'); + $generator->setAttribute('uri', 'https://github.com/fguillot/picoFeed'); + $feed->appendChild($generator); + + // <title/> + $title = $this->dom->createElement('title'); + $title->appendChild($this->dom->createTextNode($this->title)); + $feed->appendChild($title); + + // <id/> + $id = $this->dom->createElement('id'); + $id->appendChild($this->dom->createTextNode($this->site_url)); + $feed->appendChild($id); + + // <updated/> + $this->addUpdated($feed, $this->updated); + + // <link rel="alternate" type="text/html" href="http://example.org/"/> + $this->addLink($feed, $this->site_url); + + // <link rel="self" type="application/atom+xml" href="http://example.org/feed.atom"/> + $this->addLink($feed, $this->feed_url, 'self', 'application/atom+xml'); + + // <author/> + if (isset($this->author)) $this->addAuthor($feed, $this->author); + + // <entry/> + foreach ($this->items as $item) { + $this->checkRequiredProperties($this->required_item_properties, $item); + $feed->appendChild($this->createEntry($item)); + } + + $this->dom->appendChild($feed); + + if ($filename) { + $this->dom->save($filename); + } + else { + return $this->dom->saveXML(); + } + } + + /** + * Create item entry + * + * @access public + * @param arrray $item Item properties + * @return DomElement + */ + public function createEntry(array $item) + { + $entry = $this->dom->createElement('entry'); + + // <title/> + $title = $this->dom->createElement('title'); + $title->appendChild($this->dom->createTextNode($item['title'])); + $entry->appendChild($title); + + // <id/> + $id = $this->dom->createElement('id'); + $id->appendChild($this->dom->createTextNode(isset($item['id']) ? $item['id'] : $item['url'])); + $entry->appendChild($id); + + // <updated/> + $this->addUpdated($entry, isset($item['updated']) ? $item['updated'] : ''); + + // <published/> + if (isset($item['published'])) { + $entry->appendChild($this->dom->createElement('published', date(DATE_ATOM, $item['published']))); + } + + // <link rel="alternate" type="text/html" href="http://example.org/"/> + $this->addLink($entry, $item['url']); + + // <summary/> + if (isset($item['summary'])) { + $summary = $this->dom->createElement('summary'); + $summary->appendChild($this->dom->createTextNode($item['summary'])); + $entry->appendChild($summary); + } + + // <content/> + if (isset($item['content'])) { + $content = $this->dom->createElement('content'); + $content->setAttribute('type', 'html'); + $content->appendChild($this->dom->createCDATASection($item['content'])); + $entry->appendChild($content); + } + + // <author/> + if (isset($item['author'])) { + $this->addAuthor($entry, $item['author']); + } + + return $entry; + } + + /** + * Add Link + * + * @access public + * @param DomElement $xml XML node + * @param string $url URL + * @param string $rel Link rel attribute + * @param string $type Link type attribute + */ + public function addLink(DomElement $xml, $url, $rel = 'alternate', $type = 'text/html') + { + $link = $this->dom->createElement('link'); + $link->setAttribute('rel', $rel); + $link->setAttribute('type', $type); + $link->setAttribute('href', $url); + $xml->appendChild($link); + } + + /** + * Add publication date + * + * @access public + * @param DomElement $xml XML node + * @param integer $value Timestamp + */ + public function addUpdated(DomElement $xml, $value = 0) + { + $xml->appendChild($this->dom->createElement( + 'updated', + date(DATE_ATOM, $value ?: time()) + )); + } + + /** + * Add author + * + * @access public + * @param DomElement $xml XML node + * @param array $values Author name and email + */ + public function addAuthor(DomElement $xml, array $values) + { + $author = $this->dom->createElement('author'); + + if (isset($values['name'])) { + $name = $this->dom->createElement('name'); + $name->appendChild($this->dom->createTextNode($values['name'])); + $author->appendChild($name); + } + + if (isset($values['email'])) { + $email = $this->dom->createElement('email'); + $email->appendChild($this->dom->createTextNode($values['email'])); + $author->appendChild($email); + } + + if (isset($values['url'])) { + $uri = $this->dom->createElement('uri'); + $uri->appendChild($this->dom->createTextNode($values['url'])); + $author->appendChild($uri); + } + + $xml->appendChild($author); + } +} diff --git a/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20.php b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20.php new file mode 100644 index 000000000..efb2dd489 --- /dev/null +++ b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20.php @@ -0,0 +1,207 @@ +<?php + +namespace PicoFeed\Syndication; + +use DomDocument; +use DomAttr; +use DomElement; + +/** + * Rss 2.0 writer class + * + * @author Frederic Guillot + * @package Syndication + */ +class Rss20 extends Writer +{ + /** + * List of required properties for each feed + * + * @access private + * @var array + */ + private $required_feed_properties = array( + 'title', + 'site_url', + 'feed_url', + ); + + /** + * List of required properties for each item + * + * @access private + * @var array + */ + private $required_item_properties = array( + 'title', + 'url', + ); + + /** + * Get the Rss 2.0 document + * + * @access public + * @param string $filename Optional filename + * @return string + */ + public function execute($filename = '') + { + $this->checkRequiredProperties($this->required_feed_properties, $this); + + $this->dom = new DomDocument('1.0', 'UTF-8'); + $this->dom->formatOutput = true; + + // <rss/> + $rss = $this->dom->createElement('rss'); + $rss->setAttribute('version', '2.0'); + $rss->setAttributeNodeNS(new DomAttr('xmlns:content', 'http://purl.org/rss/1.0/modules/content/')); + $rss->setAttributeNodeNS(new DomAttr('xmlns:atom', 'http://www.w3.org/2005/Atom')); + + $channel = $this->dom->createElement('channel'); + + // <generator/> + $generator = $this->dom->createElement('generator', 'PicoFeed (https://github.com/fguillot/picoFeed)'); + $channel->appendChild($generator); + + // <title/> + $title = $this->dom->createElement('title'); + $title->appendChild($this->dom->createTextNode($this->title)); + $channel->appendChild($title); + + // <description/> + $description = $this->dom->createElement('description'); + $description->appendChild($this->dom->createTextNode(isset($this->description) ? $this->description : $this->title)); + $channel->appendChild($description); + + // <pubDate/> + $this->addPubDate($channel, $this->updated); + + // <atom:link/> + $link = $this->dom->createElement('atom:link'); + $link->setAttribute('href', $this->feed_url); + $link->setAttribute('rel', 'self'); + $link->setAttribute('type', 'application/rss+xml'); + $channel->appendChild($link); + + // <link/> + $link = $this->dom->createElement('link'); + $link->appendChild($this->dom->createTextNode($this->site_url)); + $channel->appendChild($link); + + // <webMaster/> + if (isset($this->author)) $this->addAuthor($channel, 'webMaster', $this->author); + + // <item/> + foreach ($this->items as $item) { + $this->checkRequiredProperties($this->required_item_properties, $item); + $channel->appendChild($this->createEntry($item)); + } + + $rss->appendChild($channel); + $this->dom->appendChild($rss); + + if ($filename) { + $this->dom->save($filename); + } + else { + return $this->dom->saveXML(); + } + } + + /** + * Create item entry + * + * @access public + * @param arrray $item Item properties + * @return DomElement + */ + public function createEntry(array $item) + { + $entry = $this->dom->createElement('item'); + + // <title/> + $title = $this->dom->createElement('title'); + $title->appendChild($this->dom->createTextNode($item['title'])); + $entry->appendChild($title); + + // <link/> + $link = $this->dom->createElement('link'); + $link->appendChild($this->dom->createTextNode($item['url'])); + $entry->appendChild($link); + + // <guid/> + if (isset($item['id'])) { + $guid = $this->dom->createElement('guid'); + $guid->setAttribute('isPermaLink', 'false'); + $guid->appendChild($this->dom->createTextNode($item['id'])); + $entry->appendChild($guid); + } + else { + $guid = $this->dom->createElement('guid'); + $guid->setAttribute('isPermaLink', 'true'); + $guid->appendChild($this->dom->createTextNode($item['url'])); + $entry->appendChild($guid); + } + + // <pubDate/> + $this->addPubDate($entry, isset($item['updated']) ? $item['updated'] : ''); + + // <description/> + if (isset($item['summary'])) { + $description = $this->dom->createElement('description'); + $description->appendChild($this->dom->createTextNode($item['summary'])); + $entry->appendChild($description); + } + + // <content/> + if (isset($item['content'])) { + $content = $this->dom->createElement('content:encoded'); + $content->appendChild($this->dom->createCDATASection($item['content'])); + $entry->appendChild($content); + } + + // <author/> + if (isset($item['author'])) { + $this->addAuthor($entry, 'author', $item['author']); + } + + return $entry; + } + + /** + * Add publication date + * + * @access public + * @param DomElement $xml XML node + * @param integer $value Timestamp + */ + public function addPubDate(DomElement $xml, $value = 0) + { + $xml->appendChild($this->dom->createElement( + 'pubDate', + date(DATE_RFC822, $value ?: time()) + )); + } + + /** + * Add author + * + * @access public + * @param DomElement $xml XML node + * @param string $tag Tag name + * @param array $values Author name and email + */ + public function addAuthor(DomElement $xml, $tag, array $values) + { + $value = ''; + + if (isset($values['email'])) $value .= $values['email']; + if ($value && isset($values['name'])) $value .= ' ('.$values['name'].')'; + + if ($value) { + $author = $this->dom->createElement($tag); + $author->appendChild($this->dom->createTextNode($value)); + $xml->appendChild($author); + } + } +} diff --git a/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Writer.php b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Writer.php new file mode 100644 index 000000000..3b4557dad --- /dev/null +++ b/3rdparty/fguillot/picofeed/lib/PicoFeed/Syndication/Writer.php @@ -0,0 +1,97 @@ +<?php + +namespace PicoFeed\Syndication; + +use RuntimeException; + +/** + * Base writer class + * + * @author Frederic Guillot + * @package Syndication + * @property string $description Feed description + */ +abstract class Writer +{ + /** + * Dom object + * + * @access protected + * @var \DomDocument + */ + protected $dom; + + /** + * Items + * + * @access public + * @var array + */ + public $items = array(); + + /** + * Author + * + * @access public + * @var array + */ + public $author = array(); + + /** + * Feed URL + * + * @access public + * @var string + */ + public $feed_url = ''; + + /** + * Website URL + * + * @access public + * @var string + */ + public $site_url = ''; + + /** + * Feed title + * + * @access public + * @var string + */ + public $title = ''; + + /** + * Feed modification date (timestamp) + * + * @access public + * @var integer + */ + public $updated = 0; + + /** + * Generate the XML document + * + * @abstract + * @access public + * @param string $filename Optional filename + * @return string + */ + abstract public function execute($filename = ''); + + /** + * Check required properties to generate the output + * + * @access public + * @param array $properties List of properties + * @param mixed $container Object or array container + */ + public function checkRequiredProperties(array $properties, $container) + { + foreach ($properties as $property) { + if ((is_object($container) && ! isset($container->$property)) || (is_array($container) && ! isset($container[$property]))) { + throw new RuntimeException('Required property missing: '.$property); + } + } + } +} |