]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/RssWriter.php
Remove unused var is_opera_seven
[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     public $_channel;
15     public $_image;
16     public $_textinput;
17
18     function __construct()
19     {
20         parent::__construct('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=UTF-8");
128         echo('<' . '?xml version="1.0" encoding="UTF-8" ?' . ">\n");
129         $this->printXML();
130     }
131
132     /**
133      * Create a new RDF <em>typedNode</em>.
134      *
135      * @param $type
136      * @param $properties
137      * @param bool $uri
138      * @return XmlElement
139      */
140     function __node($type, $properties, $uri = false)
141     {
142         if (!$uri)
143             $uri = $properties['link'];
144         $attr['rdf:about'] = $this->__uniquify_uri($uri);
145         return new XmlElement($type, $attr,
146             $this->__elementize($properties));
147     }
148
149     /**
150      * Check object URI for uniqueness, create a unique URI if needed.
151      *
152      * @param string $uri
153      * @return string
154      */
155     function __uniquify_uri($uri)
156     {
157         if (!$uri || isset($this->_uris_seen[$uri])) {
158             $n = count($this->_uris_seen);
159             $uri = $this->_channel->getAttr('rdf:about') . "#uri$n";
160             assert(!isset($this->_uris_seen[$uri]));
161         }
162         $this->_uris_seen[$uri] = true;
163         return $uri;
164     }
165
166     /**
167      * Convert hash of RDF properties to <em>propertyElt</em>s.
168      *
169      * @param $elements
170      * @return array
171      */
172     function __elementize($elements)
173     {
174         $out = array();
175         foreach ($elements as $prop => $val) {
176             $this->__check_predicate($prop);
177             if (is_array($val))
178                 $out[] = new XmlElement($prop, $val);
179             elseif (is_object($val))
180                 $out[] = $val; else
181                 $out[] = new XmlElement($prop, false, $val);
182         }
183         return $out;
184     }
185
186     /**
187      * Check property predicates for XMLNS sanity.
188      *
189      * @param string $name
190      */
191     function __check_predicate($name)
192     {
193         if (preg_match('/^([^:]+):[^:]/', $name, $m)) {
194             $ns = $m[1];
195             if (!$this->getAttr("xmlns:$ns")) {
196                 if (!isset($this->_modules[$ns]))
197                     die("$name: unknown namespace ($ns)");
198                 $this->setAttr("xmlns:$ns", $this->_modules[$ns]);
199             }
200         }
201     }
202
203     /**
204      * Create a <em>propertyElt</em> which references another node in the RSS.
205      *
206      * @param $predicate
207      * @param $reference
208      * @return XmlElement
209      */
210     function __ref($predicate, $reference)
211     {
212         $attr['rdf:resource'] = $reference->getAttr('rdf:about');
213         return new XmlElement($predicate, $attr);
214     }
215 }
216
217 /* Taken from mediawiki.
218  * See http://www.atomenabled.org/developers/syndication/
219  */
220 class AtomFeed extends RssWriter
221 {
222
223     // Args should include:
224     //  'title', 'link', 'description'
225     // and can include:
226     //  'URI'
227     function feed($properties, $uri = false)
228     {
229         global $LANG;
230         $attr = array('xmlns' => 'http://www.w3.org/2005/Atom',
231             'version' => '0.3', // or 1.0
232             'lang' => $LANG);
233         $this->_channel = $this->__node('feed', $attr, $properties, $uri);
234     }
235
236     /**
237      * Write output to HTTP client.
238      */
239     function __spew()
240     {
241         header("Content-Type: application/atom+xml; charset=UTF-8");
242         echo('<' . '?xml version="1.0" encoding="UTF-8" ?' . ">\n");
243         $this->printXML();
244     }
245
246     /**
247      * Create a new entry
248      *
249      * @param $type
250      * @param $attr
251      * @param bool $properties
252      * @param bool $uri
253      * @return XmlElement
254      */
255     function __node($type, $attr, $properties, $uri = false)
256     {
257         if (!$uri)
258             $uri = $properties['link'];
259         //$attr['rdf:about'] = $this->__uniquify_uri($uri);
260         return new XmlElement($type, $attr,
261             $this->__elementize($properties));
262     }
263
264     // Args should include:
265     //  'title', 'link', author, modified, issued, created, summary,
266     // and can include:
267     //  comment
268     function addItem($properties, $attr = false, $uri = false)
269     {
270         $this->_items[] = $this->__node('entry', $attr, $properties, $uri);
271     }
272
273     /**
274      * Print it.
275      */
276     function finish()
277     {
278         if (isset($this->_finished))
279             return;
280
281         $channel = &$this->_channel;
282         $items = &$this->_items;
283         if ($items)
284             $channel->pushContent($items);
285         $this->pushContent($channel);
286
287         $this->__spew();
288         $this->_finished = true;
289     }
290 }
291
292 // Local Variables:
293 // mode: php
294 // tab-width: 8
295 // c-basic-offset: 4
296 // c-hanging-comment-ender-p: nil
297 // indent-tabs-mode: nil
298 // End: