]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/RssWriter.php
Allow bold, italics or underlined for numbers
[SourceForge/phpwiki.git] / lib / RssWriter.php
1 <?php
2 /*
3  * Code for creating RSS 1.0.
4  */
5
6 /**
7  * A class for writing RSS 1.0.
8  *
9  * @see http://purl.org/rss/1.0/spec,
10  *      http://www.usemod.com/cgi-bin/mb.pl?ModWiki
11  */
12 class RssWriter extends XmlElement
13 {
14     function RssWriter()
15     {
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#'));
19
20         $this->_modules = array(
21             //Standards
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/",
25             //Proposed
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/"
35         );
36
37         $this->_uris_seen = array();
38         $this->_items = array();
39     }
40
41     function registerModule($alias, $uri)
42     {
43         assert(!isset($this->_modules[$alias]));
44         $this->_modules[$alias] = $uri;
45     }
46
47     // Args should include:
48     //  'title', 'link', 'description'
49     // and can include:
50     //  'URI'
51     function channel($properties, $uri = false)
52     {
53         $this->_channel = $this->__node('channel', $properties, $uri);
54     }
55
56     // Args should include:
57     //  'title', 'link'
58     // and can include:
59     //  'description', 'URI'
60     function addItem($properties, $uri = false)
61     {
62         $this->_items[] = $this->__node('item', $properties, $uri);
63     }
64
65     // Args should include:
66     //  'url', 'title', 'link'
67     // and can include:
68     //  'URI'
69     function image($properties, $uri = false)
70     {
71         $this->_image = $this->__node('image', $properties, $uri);
72     }
73
74     // Args should include:
75     //  'title', 'description', 'name', and 'link'
76     // and can include:
77     //  'URI'
78     function textinput($properties, $uri = false)
79     {
80         $this->_textinput = $this->__node('textinput', $properties, $uri);
81     }
82
83     /**
84      * Finish construction of RSS.
85      */
86     function finish()
87     {
88         if (isset($this->_finished))
89             return;
90
91         $channel = &$this->_channel;
92         $items = &$this->_items;
93
94         $seq = new XmlElement('rdf:Seq');
95         if ($items) {
96             foreach ($items as $item)
97                 $seq->pushContent($this->__ref('rdf:li', $item));
98         }
99         $channel->pushContent(new XmlElement('items', false, $seq));
100
101         if (isset($this->_image)) {
102             $channel->pushContent($this->__ref('image', $this->_image));
103             $items[] = $this->_image;
104         }
105         if (isset($this->_textinput)) {
106             $channel->pushContent($this->__ref('textinput', $this->_textinput));
107             $items[] = $this->_textinput;
108         }
109
110         $this->pushContent($channel);
111         if ($items)
112             $this->pushContent($items);
113
114         $this->__spew();
115         $this->_finished = true;
116     }
117
118     /**
119      * Write output to HTTP client.
120      */
121     function __spew()
122     {
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);
126         $this->printXML();
127     }
128
129     /**
130      * Create a new RDF <em>typedNode</em>.
131      */
132     function __node($type, $properties, $uri = false)
133     {
134         if (!$uri)
135             $uri = $properties['link'];
136         $attr['rdf:about'] = $this->__uniquify_uri($uri);
137         return new XmlElement($type, $attr,
138             $this->__elementize($properties));
139     }
140
141     /**
142      * Check object URI for uniqueness, create a unique URI if needed.
143      */
144     function __uniquify_uri($uri)
145     {
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]));
150         }
151         $this->_uris_seen[$uri] = true;
152         return $uri;
153     }
154
155     /**
156      * Convert hash of RDF properties to <em>propertyElt</em>s.
157      */
158     function __elementize($elements)
159     {
160         $out = array();
161         foreach ($elements as $prop => $val) {
162             $this->__check_predicate($prop);
163             if (is_array($val))
164                 $out[] = new XmlElement($prop, $val);
165             elseif (is_object($val))
166                 $out[] = $val; else
167                 $out[] = new XmlElement($prop, false, $val);
168         }
169         return $out;
170     }
171
172     /**
173      * Check property predicates for XMLNS sanity.
174      */
175     function __check_predicate($name)
176     {
177         if (preg_match('/^([^:]+):[^:]/', $name, $m)) {
178             $ns = $m[1];
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]);
183             }
184         }
185     }
186
187     /**
188      * Create a <em>propertyElt</em> which references another node in the RSS.
189      */
190     function __ref($predicate, $reference)
191     {
192         $attr['rdf:resource'] = $reference->getAttr('rdf:about');
193         return new XmlElement($predicate, $attr);
194     }
195 }
196
197 /* Taken from mediawiki.
198  * See http://www.atomenabled.org/developers/syndication/
199  */
200 class AtomFeed extends RssWriter
201 {
202
203     // Args should include:
204     //  'title', 'link', 'description'
205     // and can include:
206     //  'URI'
207     function feed($properties, $uri = false)
208     {
209         global $LANG;
210         $attr = array('xmlns' => 'http://www.w3.org/2005/Atom',
211             'version' => '0.3', // or 1.0
212             'lang' => $LANG);
213         $this->_channel = $this->__node('feed', $attr, $properties, $uri);
214     }
215
216     /**
217      * Write output to HTTP client.
218      */
219     function __spew()
220     {
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);
224         $this->printXML();
225     }
226
227     /**
228      * Create a new entry
229      */
230     function __node($type, $attr, $properties, $uri = false)
231     {
232         if (!$uri)
233             $uri = $properties['link'];
234         //$attr['rdf:about'] = $this->__uniquify_uri($uri);
235         return new XmlElement($type, $attr,
236             $this->__elementize($properties));
237     }
238
239     // Args should include:
240     //  'title', 'link', author, modified, issued, created, summary,
241     // and can include:
242     //  comment
243     function addItem($properties, $attr = false, $uri = false)
244     {
245         $this->_items[] = $this->__node('entry', $attr, $properties, $uri);
246     }
247
248     /**
249      * Print it.
250      */
251     function finish()
252     {
253         if (isset($this->_finished))
254             return;
255
256         $channel = &$this->_channel;
257         $items = &$this->_items;
258         if ($items)
259             $channel->pushContent($items);
260         $this->pushContent($channel);
261
262         $this->__spew();
263         $this->_finished = true;
264     }
265 }
266
267 // Local Variables:
268 // mode: php
269 // tab-width: 8
270 // c-basic-offset: 4
271 // c-hanging-comment-ender-p: nil
272 // indent-tabs-mode: nil
273 // End: