422747f0db6773319a0acea6a50aef223b74ee42
[xhtml-compiler.git] / XHTMLCompiler / DOMFilter / RSSGenerator.php
blob422747f0db6773319a0acea6a50aef223b74ee42
1 <?php
3 /**
4 * Generates an RSS feed from a specially designed HTML container indicated
5 * by rss:for.
6 */
7 class XHTMLCompiler_DOMFilter_RSSGenerator extends XHTMLCompiler_DOMFilter
10 protected $name = 'RSSGenerator';
11 protected $prefix = 'rss';
13 // new namespace defines the following attributes:
14 // for - IDREF to an element where we are to get the RSS info from
16 public function process(DOMDocument $dom, $page, $manager) {
18 // attempt to find declarations of the namespace
19 $nodes = $this->query(
20 "//attribute::*[namespace-uri() = '".$this->ns."']"
22 if (!$nodes->length) return;
24 // grab the document's links to RSS feeds
25 // we require that the link have a href, a title and a type
26 // as well as an rss:for attribute specifying where to grab data
27 $links = $this->query('//html:link[@rss:for]');
29 foreach ($links as $link) {
30 $this->generateRSS($dom, $link, $page);
35 /**
36 * Generates the RSS feed for a specific link in a document
37 * @param $link <link> DOMElement we're generating feed for
38 * @param $page Page we're generating for
40 protected function generateRSS($dom, $link, $page) {
42 // retrieve web-path of the page
43 $path = $page->getWebPath();
44 $xc = XHTMLCompiler::getInstance();
46 // generate RSS template
47 $rss = new XHTMLCompiler_RSSFeed(
48 $link->getAttribute('title'),
49 $path,
50 $this->confiscateAttr($link, $this->ns, 'description'),
51 $lang = $dom->documentElement->getAttribute('xml:lang')
54 // retrieve data source
55 $id = $this->confiscateAttr($link, $this->ns, 'for');
56 $data_source = $dom->getElementById($id);
58 // parse data source, add news items
59 foreach ($data_source->childNodes as $src_item) {
60 if (! $src_item instanceof DOMElement) continue;
61 if ($src_item->getAttribute('class') !== 'item') continue;
63 $title = $date = $body = '';
64 foreach ($src_item->childNodes as $element) {
65 if (! $element instanceof DOMElement) continue;
66 $var = $element->getAttribute('class');
67 if ($var == 'date') {
68 if (($node = $element->childNodes->item(0)) instanceof DOMElement) {
69 // If we are using human readable dates but
70 // non-parseable machine dates, an abbr
71 // element should be inside the element with class="date"
72 // with a class atNNN where NNN is the Unix timestamp
73 // of publishing.
74 $datetime = new DateTime('@' . substr($node->getAttribute('class'), 2));
75 $date = $datetime->format('r');
76 } else {
77 $date = $element->textContent;
79 } elseif ($var == 'permalink') {
80 $permalink = $element->childNodes->item(0)->getAttribute('href');
81 } elseif ($var == 'title' || $var == 'body') {
82 $$var = $element->textContent;
86 if (isset($permalink)) {
87 // assume that the permalink is an absolute path
88 if ($permalink[0] !== '/') {
89 trigger_error("Permalink for '$title' is not absolute");
90 continue;
92 $article_link = 'http://' . $xc->getConf('web_domain') . $permalink;
93 } else {
94 // determine the article link, based off anchors
95 $item_id = $src_item->getAttribute('id');
96 if (!$item_id) {
97 trigger_error("News item '$title' has no ID");
98 continue;
100 $article_link = $path . '#' . $item_id;
102 $rss->addItem($article_link, $title, $date, $body);
106 // save the feed
107 $rss->save(
108 $page->normalizePath(
109 $link->getAttribute('href')