3 * Code for creating RSS 1.0.
7 * A class for writing RSS 1.0.
9 * @see http://purl.org/rss/1.0/spec,
10 * http://www.usemod.com/cgi-bin/mb.pl?ModWiki
12 class RssWriter extends XmlElement
16 $this->XmlElement('rdf:RDF',
17 array('xmlns' => "http://purl.org/rss/1.0/",
18 'xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'));
20 $this->_modules = array(
22 'content' => "http://purl.org/rss/1.0/modules/content/",
23 'dc' => "http://purl.org/dc/elements/1.1/",
24 'sy' => "http://purl.org/rss/1.0/modules/syndication/",
26 'wiki' => "http://purl.org/rss/1.0/modules/wiki/",
27 'ag' => "http://purl.org/rss/1.0/modules/aggregation/",
28 'annotate' => "http://purl.org/rss/1.0/modules/annotate/",
29 'audio' => "http://media.tangent.org/rss/1.0/",
30 'cp' => "http://my.theinfo.org/changed/1.0/rss/",
31 'rss091' => "http://purl.org/rss/1.0/modules/rss091/",
32 'slash' => "http://purl.org/rss/1.0/modules/slash/",
33 'taxo' => "http://purl.org/rss/1.0/modules/taxonomy/",
34 'thr' => "http://purl.org/rss/1.0/modules/threading/"
37 $this->_uris_seen = array();
38 $this->_items = array();
41 function registerModule($alias, $uri)
43 assert(!isset($this->_modules[$alias]));
44 $this->_modules[$alias] = $uri;
47 // Args should include:
48 // 'title', 'link', 'description'
51 function channel($properties, $uri = false)
53 $this->_channel = $this->__node('channel', $properties, $uri);
56 // Args should include:
59 // 'description', 'URI'
60 function addItem($properties, $uri = false)
62 $this->_items[] = $this->__node('item', $properties, $uri);
65 // Args should include:
66 // 'url', 'title', 'link'
69 function image($properties, $uri = false)
71 $this->_image = $this->__node('image', $properties, $uri);
74 // Args should include:
75 // 'title', 'description', 'name', and 'link'
78 function textinput($properties, $uri = false)
80 $this->_textinput = $this->__node('textinput', $properties, $uri);
84 * Finish construction of RSS.
88 if (isset($this->_finished))
91 $channel = &$this->_channel;
92 $items = &$this->_items;
94 $seq = new XmlElement('rdf:Seq');
96 foreach ($items as $item)
97 $seq->pushContent($this->__ref('rdf:li', $item));
99 $channel->pushContent(new XmlElement('items', false, $seq));
101 if (isset($this->_image)) {
102 $channel->pushContent($this->__ref('image', $this->_image));
103 $items[] = $this->_image;
105 if (isset($this->_textinput)) {
106 $channel->pushContent($this->__ref('textinput', $this->_textinput));
107 $items[] = $this->_textinput;
110 $this->pushContent($channel);
112 $this->pushContent($items);
115 $this->_finished = true;
119 * Write output to HTTP client.
123 header("Content-Type: application/xml; charset=" . RSS_ENCODING);
124 echo('<' . '?xml version="1.0" encoding="' . RSS_ENCODING . '"?' . ">\n");
125 //printf("<!-- generator=\"PhpWiki-%s\" -->\n", PHPWIKI_VERSION);
130 * Create a new RDF <em>typedNode</em>.
132 function __node($type, $properties, $uri = false)
135 $uri = $properties['link'];
136 $attr['rdf:about'] = $this->__uniquify_uri($uri);
137 return new XmlElement($type, $attr,
138 $this->__elementize($properties));
142 * Check object URI for uniqueness, create a unique URI if needed.
144 function __uniquify_uri($uri)
146 if (!$uri || isset($this->_uris_seen[$uri])) {
147 $n = count($this->_uris_seen);
148 $uri = $this->_channel->getAttr('rdf:about') . "#uri$n";
149 assert(!isset($this->_uris_seen[$uri]));
151 $this->_uris_seen[$uri] = true;
156 * Convert hash of RDF properties to <em>propertyElt</em>s.
158 function __elementize($elements)
161 foreach ($elements as $prop => $val) {
162 $this->__check_predicate($prop);
164 $out[] = new XmlElement($prop, $val);
165 elseif (is_object($val))
167 $out[] = new XmlElement($prop, false, $val);
173 * Check property predicates for XMLNS sanity.
175 function __check_predicate($name)
177 if (preg_match('/^([^:]+):[^:]/', $name, $m)) {
179 if (!$this->getAttr("xmlns:$ns")) {
180 if (!isset($this->_modules[$ns]))
181 die("$name: unknown namespace ($ns)");
182 $this->setAttr("xmlns:$ns", $this->_modules[$ns]);
188 * Create a <em>propertyElt</em> which references another node in the RSS.
190 function __ref($predicate, $reference)
192 $attr['rdf:resource'] = $reference->getAttr('rdf:about');
193 return new XmlElement($predicate, $attr);
197 /* Taken from mediawiki.
198 * See http://www.atomenabled.org/developers/syndication/
200 class AtomFeed extends RssWriter
203 // Args should include:
204 // 'title', 'link', 'description'
207 function feed($properties, $uri = false)
210 $attr = array('xmlns' => 'http://www.w3.org/2005/Atom',
211 'version' => '0.3', // or 1.0
213 $this->_channel = $this->__node('feed', $attr, $properties, $uri);
217 * Write output to HTTP client.
221 header("Content-Type: application/atom+xml; charset=" . RSS_ENCODING);
222 echo('<' . '?xml version="1.0" encoding="' . RSS_ENCODING . '"?' . ">\n");
223 //printf("<!-- generator=\"PhpWiki-%s\" -->\n", PHPWIKI_VERSION);
230 function __node($type, $attr, $properties, $uri = false)
233 $uri = $properties['link'];
234 //$attr['rdf:about'] = $this->__uniquify_uri($uri);
235 return new XmlElement($type, $attr,
236 $this->__elementize($properties));
239 // Args should include:
240 // 'title', 'link', author, modified, issued, created, summary,
243 function addItem($properties, $attr = false, $uri = false)
245 $this->_items[] = $this->__node('entry', $attr, $properties, $uri);
253 if (isset($this->_finished))
256 $channel = &$this->_channel;
257 $items = &$this->_items;
259 $channel->pushContent($items);
260 $this->pushContent($channel);
263 $this->_finished = true;
271 // c-hanging-comment-ender-p: nil
272 // indent-tabs-mode: nil