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