]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/RssWriter.php
remove final \n to be ob_cache independent
[SourceForge/phpwiki.git] / lib / RssWriter.php
1 <?php rcs_id('$Id: RssWriter.php,v 1.10 2004-11-21 11:59:16 rurban Exp $');
2 /*
3  * Code for creating RSS 1.0.
4  */
5
6 // Encoding for RSS output.
7 define('RSS_ENCODING', $GLOBALS['charset']);
8
9 /**
10  * A class for writing RSS 1.0.
11  *
12  * @see http://purl.org/rss/1.0/spec,
13  *      http://www.usemod.com/cgi-bin/mb.pl?ModWiki
14  */
15 class RssWriter extends XmlElement
16 {
17     function RssWriter () {
18         $this->XmlElement('rdf:RDF',
19                           array('xmlns' => "http://purl.org/rss/1.0/",
20                                 'xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'));
21
22         $this->_modules = array(
23             //Standards
24             'content'   => "http://purl.org/rss/1.0/modules/content/",
25             'dc'        => "http://purl.org/dc/elements/1.1/",
26             'sy'        => "http://purl.org/rss/1.0/modules/syndication/",
27             //Proposed
28             'wiki'      => "http://purl.org/rss/1.0/modules/wiki/",
29             'ag'        => "http://purl.org/rss/1.0/modules/aggregation/",
30             'annotate'  => "http://purl.org/rss/1.0/modules/annotate/",
31             'audio'     => "http://media.tangent.org/rss/1.0/",
32             'cp'        => "http://my.theinfo.org/changed/1.0/rss/",
33             'rss091'    => "http://purl.org/rss/1.0/modules/rss091/",
34             'slash'     => "http://purl.org/rss/1.0/modules/slash/",
35             'taxo'      => "http://purl.org/rss/1.0/modules/taxonomy/",
36             'thr'       => "http://purl.org/rss/1.0/modules/threading/"
37             );
38
39         $this->_uris_seen = array();
40         $this->_items = array();
41     }
42
43     function registerModule($alias, $uri) {
44         assert(!isset($this->_modules[$alias]));
45         $this->_modules[$alias] = $uri;
46     }
47         
48     // Args should include:
49     //  'title', 'link', 'description'
50     // and can include:
51     //  'URI'
52     function channel($properties, $uri = false) {
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         $this->_items[] = $this->__node('item', $properties, $uri);
62     }
63
64     // Args should include:
65     //  'url', 'title', 'link'
66     // and can include:
67     //  'URI'
68     function image($properties, $uri = false) {
69         $this->_image = $this->__node('image', $properties, $uri);
70     }
71
72     // Args should include:
73     //  'title', 'description', 'name', and 'link'
74     // and can include:
75     //  'URI'
76     function textinput($properties, $uri = false) {
77         $this->_textinput = $this->__node('textinput', $properties, $uri);
78     }
79
80     /**
81      * Finish construction of RSS.
82      */
83     function finish() {
84         if (isset($this->_finished))
85             return;
86
87         $channel = &$this->_channel;
88         $items = &$this->_items;
89
90         $seq = new XmlElement('rdf:Seq');
91         if ($items) {
92             foreach ($items as $item)
93                 $seq->pushContent($this->__ref('rdf:li', $item));
94         }
95         $channel->pushContent(new XmlElement('items', false, $seq));
96      
97         if (isset($this->_image)) {
98             $channel->pushContent($this->__ref('image', $this->_image));
99             $items[] = $this->_image;
100         }
101         if (isset($this->_textinput)) {
102             $channel->pushContent($this->__ref('textinput', $this->_textinput));
103             $items[] = $this->_textinput;
104         }
105
106         $this->pushContent($channel);
107         if ($items)
108             $this->pushContent($items);
109
110         $this->__spew();
111         $this->_finished = true;
112     }
113             
114
115     /**
116      * Write output to HTTP client.
117      */
118     function __spew() {
119         header("Content-Type: application/xml; charset=" . RSS_ENCODING);
120         printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", RSS_ENCODING);
121         $this->printXML();
122     }
123         
124     
125     /**
126      * Create a new RDF <em>typedNode</em>.
127      */
128     function __node($type, $properties, $uri = false) {
129         if (! $uri)
130             $uri = $properties['link'];
131         $attr['rdf:about'] = $this->__uniquify_uri($uri);
132         return new XmlElement($type, $attr,
133                               $this->__elementize($properties));
134     }
135
136     /**
137      * Check object URI for uniqueness, create a unique URI if needed.
138      */
139     function __uniquify_uri ($uri) {
140         if (!$uri || isset($this->_uris_seen[$uri])) {
141             $n = count($this->_uris_seen);
142             $uri = $this->_channel->getAttr('rdf:about') . "#uri$n";
143             assert(!isset($this->_uris_seen[$uri]));
144         }
145         $this->_uris_seen[$uri] = true;
146         return $uri;
147     }
148
149     /**
150      * Convert hash of RDF properties to <em>propertyElt</em>s.
151      */
152     function __elementize ($elements) {
153         $out = array();
154         foreach ($elements as $prop => $val) {
155             $this->__check_predicate($prop);
156             $out[] = new XmlElement($prop, false, $val);
157         }
158         return $out;
159     }
160
161     /**
162      * Check property predicates for XMLNS sanity.
163      */
164     function __check_predicate ($name) {
165         if (preg_match('/^([^:]+):[^:]/', $name, $m)) {
166             $ns = $m[1];
167             if (! $this->getAttr("xmlns:$ns")) {
168                 if (!isset($this->_modules[$ns]))
169                     die("$name: unknown namespace ($ns)");
170                 $this->setAttr("xmlns:$ns", $this->_modules[$ns]);
171             }
172         }
173     }
174
175     /**
176      * Create a <em>propertyElt</em> which references another node in the RSS.
177      */
178     function __ref($predicate, $reference) {
179         $attr['rdf:resource'] = $reference->getAttr('rdf:about');
180         return new XmlElement($predicate, $attr);
181     }
182 };
183
184
185 // (c-file-style: "gnu")
186 // Local Variables:
187 // mode: php
188 // tab-width: 8
189 // c-basic-offset: 4
190 // c-hanging-comment-ender-p: nil
191 // indent-tabs-mode: nil
192 // End:   
193 ?>