Have filters add self as dependencies, rm whitespace.
[xhtml-compiler.git] / XHTMLCompiler / DOMFilter / RSSGenerator.php
blob0d99c9905872a8fb680ce96bdddfbe6e4366ad1a
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;
23 $manager->addDependency(__FILE__);
25 // grab the document's links to RSS feeds
26 // we require that the link have a href, a title and a type
27 // as well as an rss:for attribute specifying where to grab data
28 $links = $this->query('//html:link[@rss:for]');
30 foreach ($links as $link) {
31 $this->generateRSS($dom, $link, $page);
36 /**
37 * Generates the RSS feed for a specific link in a document
38 * @param $link <link> DOMElement we're generating feed for
39 * @param $page Page we're generating for
41 protected function generateRSS($dom, $link, $page) {
43 // retrieve web-path of the page
44 $path = $page->getWebPath();
45 $xc = XHTMLCompiler::getInstance();
47 // generate RSS template
48 $rss = new XHTMLCompiler_RSSFeed(
49 $link->getAttribute('title'),
50 $path,
51 $this->confiscateAttr($link, $this->ns, 'description'),
52 $lang = $dom->documentElement->getAttribute('xml:lang')
55 // retrieve data source
56 $id = $this->confiscateAttr($link, $this->ns, 'for');
57 $data_source = $dom->getElementById($id);
59 // parse data source, add news items
60 foreach ($data_source->childNodes as $src_item) {
61 if (! $src_item instanceof DOMElement) continue;
62 if ($src_item->getAttribute('class') !== 'item') continue;
64 $title = $date = $body = '';
65 foreach ($src_item->childNodes as $element) {
66 if (! $element instanceof DOMElement) continue;
67 $var = $element->getAttribute('class');
68 if ($var == 'date') {
69 if (($node = $element->childNodes->item(0)) instanceof DOMElement) {
70 // If we are using human readable dates but
71 // non-parseable machine dates, an abbr
72 // element should be inside the element with class="date"
73 // with a class atNNN where NNN is the Unix timestamp
74 // of publishing.
75 $datetime = new DateTime('@' . substr($node->getAttribute('class'), 2));
76 $date = $datetime->format('r');
77 } else {
78 $date = $element->textContent;
80 } elseif ($var == 'permalink') {
81 $permalink = $element->childNodes->item(0)->getAttribute('href');
82 } elseif ($var == 'title' || $var == 'body') {
83 $$var = $element->textContent;
87 if (isset($permalink)) {
88 // assume that the permalink is an absolute path
89 if ($permalink[0] !== '/') {
90 trigger_error("Permalink for '$title' is not absolute");
91 continue;
93 $article_link = 'http://' . $xc->getConf('web_domain') . $permalink;
94 } else {
95 // determine the article link, based off anchors
96 $item_id = $src_item->getAttribute('id');
97 if (!$item_id) {
98 trigger_error("News item '$title' has no ID");
99 continue;
101 $article_link = $path . '#' . $item_id;
103 $rss->addItem($article_link, $title, $date, $body);
107 // save the feed
108 $rss->save(
109 $page->normalizePath(
110 $link->getAttribute('href')