]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/RssParser.php
include [all] Include and file path should be devided with single space. File path...
[SourceForge/phpwiki.git] / lib / RssParser.php
1 <?php // -*-php-*-
2
3 /**
4  * Simple RSSParser Class
5  * Based on Duncan Gough RSSParser class
6  * Copyleft Arnaud Fontaine
7  * Licence : GPL
8  * See lib/plugin/RssFeed.php and lib/XmlParser.php
9  *
10  * The myth of RSS compatibility:
11  *   http://diveintomark.org/archives/2004/02/04/incompatible-rss
12  */
13
14 /*
15  * This file is part of PhpWiki.
16  *
17  * PhpWiki is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * PhpWiki is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License along
28  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
29  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30  */
31
32 /**
33  * 2004-04-09 16:30:50 rurban:
34  *   added fsockopen allow_url_fopen = Off workaround
35  * 2004-04-12 20:04:12 rurban:
36  *   fixes for IMAGE element (sf.net)
37  * 2005-04-10 11:17:35 rurban
38  *   certain RSS dont contain <item> tags to describe the list of <items>
39  *     http://ws.audioscrobbler.com/rdf/ for example
40  */
41
42 require_once 'lib/XmlParser.php';
43
44 class RSSParser
45 extends XmlParser {
46
47     var $title = "";
48     var $author = "";
49     var $pubDate = "";
50     var $link  = "";
51     var $description = "";
52     var $inside_item = false;
53     var $list_items = false;
54     var $item  = array();
55     var $items;
56     var $channel;
57     var $divers = "";
58     var $date = "";
59
60     function tag_open($parser, $name, $attrs=''){
61         global $current_tag, $current_attrs;
62
63         $current_tag = $name;
64         $current_attrs = $attrs;
65         if ($name == "ITEM")
66             $this->inside_item = true;
67         elseif ($name == "ITEMS")
68             $this->list_items = true;
69         elseif ($name == "IMAGE")
70             $this->inside_item = true;
71     }
72
73     function tag_close($parser, $tagName, $attrs=''){
74         global $current_tag;
75
76         if ($tagName == "ITEM") {
77             if (empty($this->items)) {
78                 $this->items = array();
79                 $GLOBALS['rss_parser_items'] =& $this->items;
80             } elseif (!empty($this->items[0]['link']) and $this->items[0]['title'] == '') {
81                 // override the initial <items> list with detailed <item>'s
82                 $this->items = array();
83                 $GLOBALS['rss_parser_items'] =& $this->items;
84             }
85             $this->items[] = array("title"       => $this->item['TITLE'],
86                                    "author"      => $this->item['AUTHOR'],
87                                    "pubDate"     => $this->item['PUBDATE'],
88                                    "description" => @$this->item['DESCRIPTION'],
89                                    "link"        => $this->item['LINK']);
90             $this->item = array("TITLE"       => "",
91                                 "DESCRIPTION" => "",
92                                 "LINK"        => "");
93             $this->inside_item = false;
94         } elseif ($tagName == "IMAGE") {
95             $this->item = array("TITLE"       => "",
96                                 "DESCRIPTION" => "",
97                                 "LINK"        => "");
98             $this->inside_item = false;
99         } elseif ($tagName == "CHANNEL") {
100             $this->channel = array("title" => $this->title,
101                                    "description" => $this->description,
102                                    "link" => $this->link,
103                                    "date" => $this->date,
104                                    "divers" => $this->divers);
105             $GLOBALS['rss_parser_channel'] =& $this->channel;
106             $this->title       = "";
107             $this->description = "";
108             $this->link        = "";
109             $this->divers      = "";
110             $this->date        = "";
111         } elseif ($tagName == "ITEMS") {
112             $GLOBALS['rss_parser_items'] =& $this->items;
113             $this->item = array("TITLE"       => "",
114                                 "DESCRIPTION" => "",
115                                 "LINK"        => "");
116             $this->list_items = false;
117         }
118     }
119
120     function cdata($parser, $data){
121         global $current_tag, $current_attrs;
122
123         if ($this->inside_item) {
124             if (empty($this->item[$current_tag]))
125                 $this->item[$current_tag] = '';
126             if ($current_tag == 'LINK') {
127                 if (trim($data))
128                     $this->item[$current_tag] = trim($data);
129             } else {
130                 $this->item[$current_tag] .= trim($data);
131             }
132         } elseif ($this->list_items) {
133             if ($current_tag == 'RDF:LI') {
134                 // FIXME: avoid duplicates. cdata called back 4x per RDF:LI
135                 if ($this->items[count($this->items)-1]['link'] != @$current_attrs['RDF:RESOURCE'])
136                     $this->items[] = array('link' => @$current_attrs['RDF:RESOURCE'],
137                                            'title' => '');
138             }
139         } else {
140             switch ($current_tag) {
141             case "TITLE":
142                 if (trim($data))
143                     $this->title .= " " . trim($data);
144                 break;
145             case "DESCRIPTION":
146                 if (trim($data))
147                     $this->description .= trim($data);
148                 break;
149             case "LINK":
150                 if (trim($data))
151                     $this->link = trim($data);
152                 break;
153             case "DC:DATE":
154                 if (trim($data))
155                     $this->date .= " " . trim($data);
156             default:
157                 if (trim($data))
158                     $this->divers .= " " . $current_tag."/".$data;
159                 break;
160             }
161         }
162     }
163
164     function parse($content, $is_final = true) {
165         xml_parse($this->_parser, $content, $is_final) or
166             trigger_error(sprintf("XML error: %s at line %d",
167                                   xml_error_string(xml_get_error_code($this->_parser)),
168                                   xml_get_current_line_number($this->_parser)),
169                           E_USER_WARNING);
170         //OO workaround: parser object looses its params. we have to store them in globals
171         if ($is_final) {
172             if (empty($this->items)) {
173                 $this->items   = @$GLOBALS['rss_parser_items'];
174                 $this->channel = @$GLOBALS['rss_parser_channel'];
175             }
176             unset($GLOBALS['rss_parser_items']);
177             unset($GLOBALS['rss_parser_channel']);
178         }
179     }
180 }
181
182 // Local Variables:
183 // mode: php
184 // tab-width: 8
185 // c-basic-offset: 4
186 // c-hanging-comment-ender-p: nil
187 // indent-tabs-mode: nil
188 // End: